Merge pull request #20 from Kiritow/master

Catch up with master
pull/38/head
KiritoTRw 2016-08-22 00:31:49 +08:00 committed by GitHub
commit 357541214f
19 changed files with 1616 additions and 31 deletions

View File

@ -1,30 +1,29 @@
/// LCS 最长子序列
namespace LCS
{
const int MAXLEN_A = 500;
const int MAXLEN_B = 500;
int dp[MAXLEN_A+5][MAXLEN_B+5];
int deal(const char* a,const char* b)
{
int lena=strlen(a);
int lenb=strlen(b);
for(int i=0;i<lenb;i++)
{
for(int j=0;j<lena;j++)
{
if(i==0) dp[i][j]=0;
else if(b[i]==a[j])
{
if(j!=0) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=1;
}
else
{
if(j!=0) dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
else dp[i][j]=dp[i-1][j];
}
}
}
return dp[lenb-1][lena-1];
}
}//End of namespace LCS
/// LCS 最长子序列
namespace LCS
{
const int MAXLEN_A = 512;
const int MAXLEN_B = 512;
int dp[MAXLEN_A][MAXLEN_B];
int deal(const char* a,const char* b)
{
int lena=strlen(a);
int lenb=strlen(b);
for(int i=0;i<=lenb;i++)
{
for(int j=0;j<=lena;j++)
{
if(i==0) dp[i][j]=0;
else if(j==0) dp[i][j]=0;
else if(b[i-1]==a[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
}
else
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[lenb][lena];
}
}//End of namespace LCS

View File

@ -384,3 +384,159 @@ int query(int Val,int _indexer=1)
}
}/// End of namespace AttributeMergeSegmentTree
/// 最长连续上升字串 与线段树结合 (LCIS & Segment Tree)
namespace LCISSegmentTree
{
const int MAXN = 1000100;
const int MAXTREENODE = MAXN<<2;
int seq[MAXN];
struct node
{
/// Be Sure That "BounderLen" always equal to "RightBounder - LeftBounder + 1"
/// And Bounder Never change in one single test.
int leftbounder,rightbounder,bounderlen;
int leftseqlen,rightseqlen,mergedseqlen; /// From HDU 3308
int leftvalue,rightvalue;
};
node tree[MAXTREENODE];
/// _internal_v is a indexer of SegmentTree. It guides the procedure to the right node.
void pushup(int _internal_v)
{
/// Left == Left.Left
tree[_internal_v].leftseqlen=tree[_internal_v<<1].leftseqlen;
tree[_internal_v].leftvalue=tree[_internal_v<<1].leftvalue;
/// Right == Right.Right
tree[_internal_v].rightseqlen=tree[_internal_v<<1|1].rightseqlen;
tree[_internal_v].rightvalue=tree[_internal_v<<1|1].rightvalue;
/// Merged SeqLen is the max one of two sub-tree.MergedSeqLen
tree[_internal_v].mergedseqlen=max(tree[_internal_v<<1].mergedseqlen,tree[_internal_v<<1|1].mergedseqlen);
/// If LeftSon.RightValue < RightSon.LeftValue, a longer Seq may exist.
if(tree[_internal_v<<1].rightvalue<tree[_internal_v<<1|1].leftvalue)
{
/// If LeftSon.LeftSeqLen == LeftSon.BounderLen ...
if(tree[_internal_v<<1].leftseqlen == tree[_internal_v<<1].bounderlen )
{
/// ... ThisNode.LeftSeqLen += RightSon.LeftSeqLen
tree[_internal_v].leftseqlen+=tree[_internal_v<<1|1].leftseqlen;
}
/// If RightSon.RightSeqLen == RightSon.BounderLen ...
if(tree[_internal_v<<1|1].rightseqlen == tree[_internal_v<<1|1].bounderlen )
{
/// ... ThisNode.RightSeqLen += Left.RightSeqLen
tree[_internal_v].rightseqlen+=tree[_internal_v<<1].rightseqlen;
}
/// ThisNode.MergedSeqLen is the max one between itself and ...
/// ... LeftSon.RightSeqLen + RightSon.LeftSeqLen
tree[_internal_v].mergedseqlen=
max(tree[_internal_v].mergedseqlen,
tree[_internal_v<<1].rightseqlen+tree[_internal_v<<1|1].leftseqlen);
}
}
void build(int L,int R,int _internal_v=1) /// Build a tree, _internal_v is 1 by default.
{
tree[_internal_v].leftbounder=L;
tree[_internal_v].rightbounder=R;
tree[_internal_v].bounderlen=R-L+1;
if(L==R)
{
tree[_internal_v].leftvalue=tree[_internal_v].rightvalue=seq[L];
/** SeqLen of Single Position is 1 , of course*/
tree[_internal_v].leftseqlen=
tree[_internal_v].rightseqlen=
tree[_internal_v].mergedseqlen=1;
return;
}
int mid=(L+R)>>1;
build(L,mid,_internal_v<<1);
build(mid+1,R,_internal_v<<1|1);/// x<<1 == x*2; x<<1|1 == x*2+1; (faster == slower)
/// Push Up
pushup(_internal_v);
}
void update(int Pos,int Val,int _internal_v=1)/// Update a position, _internal_v is 1 by default.
{
/// Reach a clearly node with same LeftBounder and RightBounder
if(tree[_internal_v].leftbounder==tree[_internal_v].rightbounder)
{
tree[_internal_v].leftvalue=tree[_internal_v].rightvalue=Val;
return;
}
/// Calculate Mid
int mid=(tree[_internal_v].leftbounder+tree[_internal_v].rightbounder)>>1;
/// If in left then try update in left
if(Pos <= mid)
update(Pos,Val,_internal_v<<1);
else /// Else try update in right
update(Pos,Val,_internal_v<<1|1);
/// And then push it up !
pushup(_internal_v);
}
int query(int L,int R,int _internal_v=1)
{
/// This Node ( and the segment which is under its control )
/// is included in query area.
if(L<=tree[_internal_v].leftbounder && tree[_internal_v].rightbounder <= R)
{
return tree[_internal_v].mergedseqlen;
}
/// Calculate Mid
int mid=(tree[_internal_v].leftbounder+tree[_internal_v].rightbounder)>>1;
/// Answer saved in 'ans'
int ans=0;
/// Query If Segment L~R has common area with ThisNode.LeftBounder~Mid
if(L<=mid)
{
ans=max(ans,query(L,R,_internal_v<<1));
}
/// Query If Segment L~R has common area with Mid+1 ~ ThisNode.RightBounder
if(mid<R)
{
ans=max(ans,query(L,R,_internal_v<<1|1));
}
/// Besides these conditions, the following condition is more complex...
/// If LeftNode.RightValue < RightNode.LeftValue
/// (looks like Push Up, but why not push up here ?
/// Is the amount of query action so huge ? )
if(tree[_internal_v<<1].rightvalue<tree[_internal_v<<1|1].leftvalue)
{
/// Here comes the most complex logic.
/// Answer is the max one of ...
ans=max(ans,
/// the minimum one of "Mid - L + 1" (Actually Left Bounder)
/// and LeftSon.RightSeqLen
min(mid-L+1,tree[_internal_v<<1].rightseqlen)
/// and
+
/// the minimum one of "R - Mid" (Actually Right Bounder)
/// and RightSon.LeftSeqLen
min(R-mid,tree[_internal_v<<1|1].leftseqlen)
);
}
/// Return ans. Ans is at least 1
return ans;
}
}/// End of namespace LCISSegmentTree

View File

@ -0,0 +1,129 @@
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stdio.h>
using namespace std;
int q;
int sz = 1;
struct node
{
int zero;
int one;
int cnt1;
int cnt0;
}a[10000000];
int main()
{
cin >> q;
for (int i = 0; i <= q; i++)
{
char c;
int x;
if(i==0)
{
c='+';
x=0;
}
else
cin >> c >> x;
if (c == '+')
{
int bit[32];
for (int i = 0; i < 32; i++)
{
bit[i] = x % 2;
x /= 2;
}
int v = 1;
for (int i = 31; i >= 0; i--)
{
if (bit[i] == 1)
{
a[v].cnt1++;
if (a[v].one == 0)
{
sz++;
a[v].one = sz;
}
v = a[v].one;
}
else
{
a[v].cnt0++;
if (a[v].zero == 0)
{
sz++;
a[v].zero = sz;
}
v = a[v].zero;
}
}
}
if (c == '-')
{
int bit[32];
for (int i = 0; i < 32; i++)
{
bit[i] = x % 2;
x /= 2;
}
int v = 1;
for (int i = 31; i >= 0; i--)
{
if (bit[i] == 1)
{
a[v].cnt1--;
v = a[v].one;
}
else
{
a[v].cnt0--;
v = a[v].zero;
}
}
}
if (c == '?')
{
int ans = 0;
int bit[32];
for (int i = 0; i < 32; i++)
{
bit[i] = x % 2;
x /= 2;
}
int v = 1;
for (int i = 31; i >= 0; i--)
{
if (bit[i] == 1)
{
if (a[v].cnt0 > 0)
{
ans += (1 << i);
v = a[v].zero;
}
else
{
v = a[v].one;
}
}
else
{
if (a[v].cnt1 > 0)
{
ans += (1 << i);
v = a[v].one;
}
else
{
v = a[v].zero;
}
}
}
cout << ans << endl;
}
}
}

49
HDOJ/1159.cpp Normal file
View File

@ -0,0 +1,49 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
/// LCS 最长子序列
namespace LCS
{
const int MAXLEN_A = 512;
const int MAXLEN_B = 512;
int dp[MAXLEN_A][MAXLEN_B];
int deal(const char* a,const char* b)
{
int lena=strlen(a);
int lenb=strlen(b);
for(int i=0;i<=lenb;i++)
{
for(int j=0;j<=lena;j++)
{
if(i==0) dp[i][j]=0;
else if(j==0) dp[i][j]=0;
else if(b[i-1]==a[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
}
else
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[lenb][lena];
}
}//End of namespace LCS
char stra[512];
char strb[512];
int main()
{
using namespace LCS;
while(scanf("%s %s",stra,strb)==2)
{
memset(dp,0,sizeof(dp));
int ans=deal(stra,strb);
printf("%d\n",ans);
}
return 0;
}

62
HDOJ/2795_libin56842.cpp Normal file
View File

@ -0,0 +1,62 @@
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int h,w,n;
int ans;
struct node
{
int l,r,n;
} a[1000000];
void init(int l,int r,int i,int w)//建树
{
a[i].l=l;
a[i].r=r;
a[i].n=w;
if(l!=r)
{
int mid=(l+r)/2;
init(l,mid,2*i,w);
init(mid+1,r,2*i+1,w);
}
}
void insert(int i,int x)
{
if(a[i].l == a[i].r)//到了叶子节点,叶子节点的值既是层数
{
a[i].n-=x;//该层宽度减少
ans = a[i].l;
return ;
}
if(x<=a[2*i].n)//符合要求搜左子树
insert(2*i,x);
else//否则右子树
insert(2*i+1,x);
a[i].n = max(a[2*i].n,a[2*i+1].n);//将左右子树里能放的最大长度存入父亲节点,进行更新
}
int main()
{
int i,k;
while(~scanf("%d%d%d",&h,&w,&n))
{
if(h>n)//根据题意因为最多放n个公告占用的最大高度也只有n如果根据h的大小建树由于h太大这个树根本就建不起来所以在这里就优化建树的高度
h = n;
init(1,h,1,w);
ans = -1;
for(i = 1; i<=n; i++)
{
scanf("%d",&k);
if(a[1].n>=k)//如果这个公告没有超出公告板的长度,那么才能放入
insert(1,k);
printf("%d\n",ans);
ans = -1;
}
}
return 0;
}

199
HDOJ/3308.cpp Normal file
View File

@ -0,0 +1,199 @@
/// General includes
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
/// 单点更新合并线段树: 单点更新,区间合并
namespace MergeSegmentTree
{
const int MAXN = 1000100;
const int MAXTREENODE = MAXN<<2;
int seq[MAXN];
struct node
{
/// Be Sure That "BounderLen" always equal to "RightBounder - LeftBounder + 1"
/// And Bounder Never change in one single test.
int leftbounder,rightbounder,bounderlen;
int leftseqlen,rightseqlen,mergedseqlen; /// From HDU 3308
int leftvalue,rightvalue;
};
node tree[MAXTREENODE];
/// _internal_v is a indexer of SegmentTree. It guides the procedure to the right node.
void pushup(int _internal_v)
{
/// Left == Left.Left
tree[_internal_v].leftseqlen=tree[_internal_v<<1].leftseqlen;
tree[_internal_v].leftvalue=tree[_internal_v<<1].leftvalue;
/// Right == Right.Right
tree[_internal_v].rightseqlen=tree[_internal_v<<1|1].rightseqlen;
tree[_internal_v].rightvalue=tree[_internal_v<<1|1].rightvalue;
/// Merged SeqLen is the max one of two sub-tree.MergedSeqLen
tree[_internal_v].mergedseqlen=max(tree[_internal_v<<1].mergedseqlen,tree[_internal_v<<1|1].mergedseqlen);
/// If LeftSon.RightValue < RightSon.LeftValue, a longer Seq may exist.
if(tree[_internal_v<<1].rightvalue<tree[_internal_v<<1|1].leftvalue)
{
/// If LeftSon.LeftSeqLen == LeftSon.BounderLen ...
if(tree[_internal_v<<1].leftseqlen == tree[_internal_v<<1].bounderlen )
{
/// ... ThisNode.LeftSeqLen += RightSon.LeftSeqLen
tree[_internal_v].leftseqlen+=tree[_internal_v<<1|1].leftseqlen;
}
/// If RightSon.RightSeqLen == RightSon.BounderLen ...
if(tree[_internal_v<<1|1].rightseqlen == tree[_internal_v<<1|1].bounderlen )
{
/// ... ThisNode.RightSeqLen += Left.RightSeqLen
tree[_internal_v].rightseqlen+=tree[_internal_v<<1].rightseqlen;
}
/// ThisNode.MergedSeqLen is the max one between itself and ...
/// ... LeftSon.RightSeqLen + RightSon.LeftSeqLen
tree[_internal_v].mergedseqlen=
max(tree[_internal_v].mergedseqlen,
tree[_internal_v<<1].rightseqlen+tree[_internal_v<<1|1].leftseqlen);
}
}
void build(int L,int R,int _internal_v=1) /// Build a tree, _internal_v is 1 by default.
{
tree[_internal_v].leftbounder=L;
tree[_internal_v].rightbounder=R;
tree[_internal_v].bounderlen=R-L+1;
if(L==R)
{
tree[_internal_v].leftvalue=tree[_internal_v].rightvalue=seq[L];
/** SeqLen of Single Position is 1 , of course*/
tree[_internal_v].leftseqlen=
tree[_internal_v].rightseqlen=
tree[_internal_v].mergedseqlen=1;
return;
}
int mid=(L+R)>>1;
build(L,mid,_internal_v<<1);
build(mid+1,R,_internal_v<<1|1);/// x<<1 == x*2; x<<1|1 == x*2+1; (faster == slower)
/// Push Up
pushup(_internal_v);
}
void update(int Pos,int Val,int _internal_v=1)/// Update a position, _internal_v is 1 by default.
{
/// Reach a clearly node with same LeftBounder and RightBounder
if(tree[_internal_v].leftbounder==tree[_internal_v].rightbounder)
{
tree[_internal_v].leftvalue=tree[_internal_v].rightvalue=Val;
return;
}
/// Calculate Mid
int mid=(tree[_internal_v].leftbounder+tree[_internal_v].rightbounder)>>1;
/// If in left then try update in left
if(Pos <= mid)
update(Pos,Val,_internal_v<<1);
else /// Else try update in right
update(Pos,Val,_internal_v<<1|1);
/// And then push it up !
pushup(_internal_v);
}
int query(int L,int R,int _internal_v=1)
{
/// This Node ( and the segment which is under its control )
/// is included in query area.
if(L<=tree[_internal_v].leftbounder && tree[_internal_v].rightbounder <= R)
{
return tree[_internal_v].mergedseqlen;
}
/// Calculate Mid
int mid=(tree[_internal_v].leftbounder+tree[_internal_v].rightbounder)>>1;
/// Answer saved in 'ans'
int ans=0;
/// Query If Segment L~R has common area with ThisNode.LeftBounder~Mid
if(L<=mid)
{
ans=max(ans,query(L,R,_internal_v<<1));
}
/// Query If Segment L~R has common area with Mid+1 ~ ThisNode.RightBounder
if(mid<R)
{
ans=max(ans,query(L,R,_internal_v<<1|1));
}
/// Besides these conditions, the following condition is more complex...
/// If LeftNode.RightValue < RightNode.LeftValue
/// (looks like Push Up, but why not push up here ?
/// Is the amount of query action so huge ? )
if(tree[_internal_v<<1].rightvalue<tree[_internal_v<<1|1].leftvalue)
{
/// Here comes the most complex logic.
/// Answer is the max one of ...
ans=max(ans,
/// the minimum one of "Mid - L + 1" (Actually Left Bounder)
/// and LeftSon.RightSeqLen
min(mid-L+1,tree[_internal_v<<1].rightseqlen)
/// and
+
/// the minimum one of "R - Mid" (Actually Right Bounder)
/// and RightSon.LeftSeqLen
min(R-mid,tree[_internal_v<<1|1].leftseqlen)
);
}
/// Return ans. Ans is at least 1
return ans;
}
}/// End of namespace MergeSegmentTree
using namespace MergeSegmentTree;
char _buff[8];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int N,Q;
scanf("%d %d",&N,&Q);
for(int i=1; i<=N; i++)
{
scanf("%d",&seq[i]);
}
build(1,N);
while(Q--)
{
int a,b;
scanf("%s %d %d",_buff,&a,&b);
switch(_buff[0])
{
case 'Q':
{
int ans=query(a+1,b+1);
printf("%d\n",ans);
}
break;
case 'U':
update(a+1,b);
break;
}
}
}
return 0;
}

104
HDOJ/3308_libin56842.cpp Normal file
View File

@ -0,0 +1,104 @@
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int L = 111111;
int n,m,s[L];
struct node
{
int l,r,c;//左右边界与连续的长度
int ln,rn;//左右边界的值
int ls,rs,ms,;//左右最大LCIS和区间最大LCIS
} a[L<<2];
void pushup(int i)
{
a[i].ls = a[2*i].ls;
a[i].rs = a[2*i+1].rs;
a[i].ln = a[2*i].ln;
a[i].rn = a[2*i+1].rn;
a[i].ms = max(a[2*i].ms,a[2*i+1].ms);
if(a[2*i].rn<a[2*i+1].ln)//如果左子树的右边界值小于右子树的左边界值,要合并左子树的右边界和右子树的左边界进行计算
{
if(a[2*i].ls == a[2*i].c)
a[i].ls+=a[2*i+1].ls;
if(a[2*i+1].rs == a[2*i+1].c)
a[i].rs+=a[2*i].rs;
a[i].ms = max(a[i].ms,a[2*i].rs+a[2*i+1].ls);
}
}
void init(int l,int r,int i)//建树
{
a[i].l = l;
a[i].r = r;
a[i].c = r-l+1;
if(l == r)
{
a[i].ln = a[i].rn = s[l];
a[i].ls = a[i].rs = a[i].ms = 1;
return;
}
int mid = (a[i].l+a[i].r)>>1;
init(l,mid,2*i);
init(mid+1,r,2*i+1);
pushup(i);
}
void insert(int i,int t,int m)
{
if(a[i].l == a[i].r)
{
a[i].ln = a[i].rn = m;
return;
}
int mid = (a[i].l+a[i].r)>>1;
if(t<=mid)
insert(2*i,t,m);
if(t>mid)
insert(2*i+1,t,m);
pushup(i);
}
int query(int l,int r,int i)//查询最大的LCIS
{
if(a[i].l>=l && a[i].r<=r)
{
return a[i].ms;
}
int mid = (a[i].l+a[i].r)>>1,ans = 0;
if(l<=mid)
ans = max(ans,query(l,r,2*i));
if(r>mid)
ans = max(ans,query(l,r,2*i+1));
if(a[2*i].rn < a[2*i+1].ln)
ans = max(ans , min(mid-l+1,a[2*i].rs)+min(r-mid,a[2*i+1].ls));
return ans;
}
int main()
{
int t,i,l,r;
char str[5];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i = 1; i<=n; i++)
scanf("%d",&s[i]);
init(1,n,1);
while(m--)
{
scanf("%s%d%d",str,&l,&r);
if(str[0] == 'Q')
printf("%d\n",query(l+1,r+1,1));
else
insert(1,l+1,r);
}
}
return 0;
}

View File

@ -1,2 +1,4 @@
#杭州电子科技大学 HDOJ
[Goto HDOJ](http://acm.hdu.edu.cn/listproblem.php?vol=1 "HDOJ")
[Goto HDOJ - Problem Set](http://acm.split.hdu.edu.cn/listproblem.php?vol=1 "Problem Set")
[Goto HDOJ (deprecated)](http://acm.hdu.edu.cn/listproblem.php?vol=1 "HDOJ")

129
POJ/1176_ly_Kiritow.cpp Normal file
View File

@ -0,0 +1,129 @@
#include <cstring>
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#define INF 0x3f3f3f3f
const int maxn=5010;
using namespace std;
vector <string> ans;
int a[110];//目标串
int b[110];//符合条件的某个
char tem[110];
int num=0;
int n,c;
void num1()
{
for(int i=1; i<=n; ++i)
{
b[i]=!b[i];
}
}
void num2()
{
for(int i=1; i<=n; i+=2)
{
b[i]=!b[i];
}
}
void num3()
{
for(int i=2; i<=n; i+=2)
{
b[i]=!b[i];
}
}
void num4()
{
for(int i=1; i<=n; i+=3)
{
b[i]=!b[i];
}
}
//
void dfs(int icount)
{
//if(icount > c) return ;
if(icount ==c)
{
int f=1;
for(int i=1; i<=n; ++i)
{
if(a[i]==-1) continue ;
if(a[i]!=b[i])
{
f=0;
break;
}
}
if(f==1)
{
num++;
for(int i=0; i<n; ++i)
tem[i]=b[i+1]+'0';
tem[n] = '\0';
///ans.push_back(tem);
ans.push_back((string)tem);
}
return ;
}
num1();
dfs(icount+1);
num1();
num2();
dfs(icount+1);
num2();
num3();
dfs(icount+1);
num3();
num4();
dfs(icount+1);
num4();
}
int main()
{
scanf("%d%d",&n,&c);
memset(a,-1,sizeof(a));
int x;
/**??*/
//if(c>4) c=4-c%2;
while(scanf("%d",&x) && x!=-1)
a[x]=1;
while(scanf("%d",&x) && x!=-1)
a[x]=0;
for(int i=1; i<=n; ++i)
{
b[i]=1;
}
dfs(0);
sort(ans.begin(),ans.end());
///for(int i=0; i<num; ++i)
puts(ans.at(0).c_str());
int last=0;
for(size_t i=1;i<ans.size();i++)
{
if(ans.at(i)!=ans.at(last))
{
last=i;
puts(ans.at(i).c_str());
}
}
return 0;
}

80
POJ/1178_mythit.cpp Normal file
View File

@ -0,0 +1,80 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf = 100000;
char str[150];
int k[64],king[64][64],knight[64][64];
int move1[8][2]={-1,-1,-1,0,-1,1,0,1,1,1,1,0,1,-1,0,-1};
int move2[8][2]={-1,-2,-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2};
void init(){
int i,j,x,y,tx,ty;
for(i=0;i<64;i++)
for(j=0;j<64;j++)
if(i==j) king[i][j]=knight[i][j]=0;
else king[i][j]=knight[i][j]=inf;
for(i=0;i<64;i++){
x=i/8,y=i%8;
for(j=0;j<8;j++){
tx=x+move1[j][0],ty=y+move1[j][1];
if(tx>=0 && ty>=0 && tx<8 && ty<8)
king[i][8*tx+ty]=1;
}
}
for(i=0;i<64;i++){
x=i/8,y=i%8;
for(j=0;j<8;j++){
tx=x+move2[j][0],ty=y+move2[j][1];
if(tx>=0 && ty>=0 && tx<8 && ty<8)
knight[i][8*tx+ty]=1;
}
}
}
void floyd1(){
int i,j,k;
for(k=0;k<64;k++)
for(i=0;i<64;i++)
for(j=0;j<64;j++)
if(king[i][k]+king[k][j]<king[i][j])
king[i][j]=king[i][k]+king[k][j];
}
void floyd2(){
int i,j,k;
for(k=0;k<64;k++)
for(i=0;i<64;i++)
for(j=0;j<64;j++)
if(knight[i][k]+knight[k][j]<knight[i][j])
knight[i][j]=knight[i][k]+knight[k][j];
}
int main(){
int i,j,l,cnt,pos,sum,ans,len,t1,t2;
init();
floyd1();
floyd2();
while(scanf("%s",str)!=EOF){
len=strlen(str);
pos=(str[0]-'A')+(str[1]-'1')*8;
cnt=(len-2)/2;
if(cnt==0){
printf("0\n");
continue;
}
for(i=0,j=2;i<cnt;i++,j+=2)
k[i]=(str[j]-'A')+(str[j+1]-'1')*8;
for(ans=inf,i=0;i<64;i++){
for(sum=l=0;l<cnt;l++)
sum+=knight[k[l]][i];
for(j=0;j<64;j++){
t1=king[pos][j];
for(t2=inf,l=0;l<cnt;l++)
t2=min(t2,knight[k[l]][j]+knight[j][i]-knight[k[l]][i]);
ans=min(ans,sum+t1+t2);
}
}
printf("%d\n",ans);
}
return 0;
}

102
POJ/1179_gj-Acit.cpp Normal file
View File

@ -0,0 +1,102 @@
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
#include <set>
#include <queue>
#define MAX(a,b) (a) > (b)? (a):(b)
#define MIN(a,b) (a) < (b)? (a):(b)
#define mem(a) memset(a,0,sizeof(a))
#define INF 1000000007
#define MAXN 20005
using namespace std;
bool op[105];
int num[105],dp_max[10005], dp_min[10005], n;
bool vis_max[10005],vis_min[10005];
int DP_MIN(int i,int j);
int DP_MAX(int i,int j);
int DP_MAX(int i,int j)//DP求区间最大值
{
int u = i*100+j;
if(vis_max[u])return dp_max[u];
vis_max[u]=1;
if(j-i <= 1)
{
if(j==i)return dp_max[u]=num[i-1];
if(!op[i])return dp_max[u]=num[i-1]+num[i];
else return dp_max[u]=num[i-1]*num[i];
}
dp_max[u] = -INF;
for(int k=i;k<j;k++)
{
int l=DP_MIN(i,k);
int r=DP_MIN(k+1,j);
int ll=DP_MAX(i,k);
int rr=DP_MAX(k+1,j);
if(!op[k])dp_max[u] = MAX(dp_max[u], ll+rr);
else dp_max[u] = MAX(dp_max[u], MAX(ll*rr,MAX(l*r,MAX(l*rr,r*ll))));
}
return dp_max[u];
}
int DP_MIN(int i,int j)//DP求区间最小值
{
int u = i*100+j;
if(vis_min[u])return dp_min[u];
vis_min[u]=1;
if(j-i <= 1)
{
if(j==i)return dp_min[u]=num[i-1];
if(!op[i])return dp_min[u]=num[i-1]+num[i];
else return dp_min[u]=num[i-1]*num[i];
}
dp_min[u] = INF;
for(int k=i;k<j;k++)
{
int l=DP_MIN(i,k);
int r=DP_MIN(k+1,j);
int ll=DP_MAX(i,k);
int rr=DP_MAX(k+1,j);
if(!op[k])dp_min[u] = MIN(dp_min[u], l+r);
else dp_min[u] = MIN(dp_min[u], MIN(ll*rr,MIN(l*r,MIN(l*rr,r*ll))));
}
return dp_min[u];
}
int main()
{
while(~scanf("%d%*c",&n))
{
mem(op);mem(dp_max);
mem(num);mem(vis_min);
mem(vis_max);
int max=-INF,i;
char ch;
for(i=0;i<n;i++)
{
scanf("%c %d%*c",&ch,&num[i]);
op[i]=op[i+n]=(ch=='x');
num[i+n]=num[i];
}
for(i=0;i<n;i++)
{
max=MAX(max,DP_MAX(i+1,i+n));
}
printf("%d\n",max);
int ok=1;
for(i=0;i<n;i++)
{
if(DP_MAX(i+1,i+n) == max)
{
if(ok){printf("%d",i+1);ok=0;}
else printf(" %d",i+1);
}
}
printf("\n");
}
return 0;
}

66
POJ/1189_xiaoxiaoluo.cpp Normal file
View File

@ -0,0 +1,66 @@
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int const maxn = 51 + 51 * 50 / 2;
int n, m;
long long dp[55][55];
bool triangle[maxn];
long long gcd(long long a, long long b)
{
if(b)
return gcd(b, a % b);
return a;
}
int main()
{
scanf("%d %d", &n, &m);
char s[5];
int index = 1;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= i; j++)
{
scanf("%s", s);
if(s[0] == '*')
triangle[index++] = true;
else
triangle[index++] = false;
}
}
dp[1][1] = 1;
for(int i = 1; i <= n; i++)
dp[1][1] <<= 1;
for(int i = 1; i <= n; i++)
{
int id = i * (i - 1) / 2;
for(int j = 1; j <= i; j++)
{
if(triangle[id + j])
{
dp[i+1][j] += dp[i][j] >> 1;
dp[i+1][j+1] += dp[i][j] >> 1;
}
else
{
dp[i+2][j+1] += dp[i][j];
}
}
}
long long ans1 = dp[n+1][m+1];
long long ans2 = 0;
for(int i = 1; i <= n + 1; i++)
ans2 += dp[n+1][i];
long long k = gcd(ans1,ans2);
if(ans1 == 0)
{
ans2 = 1;
k = 1;
}
printf("%lld/%lld\n", ans1 / k, ans2 / k);
}

40
POJ/1256.cpp Normal file
View File

@ -0,0 +1,40 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
char buff[1024];
//vector<string> vec;
bool cmp(const char& a,const char& b)
{
char c=a>='a'?a-'a':a-'A';
char d=b>='a'?b-'a':b-'A';
if(c!=d) return c<d;
else return a<b;
}
int main()
{
int t;
scanf("%d%*c",&t);
for(int i=0;i<t;i++)
{
gets(buff);
string str(buff);
sort(str.begin(),str.end(),cmp);
////What? You mean this is needn't?
//if(find(vec.begin(),vec.end(),str)!=vec.end()) continue;
//vec.push_back(str);
printf("%s\n",str.c_str());
while(next_permutation(str.begin(),str.end(),cmp))
{
printf("%s\n",str.c_str());
}
}
return 0;
}

View File

@ -0,0 +1,84 @@
/*
:y,线,1线
线(线)线,
线
:0,4,1 0,2,2 3,4,2线0~4线线,3(2~3)
*2,0,8,1 0,4,2 6,8,24~6线
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std;
const int MAX=8000+10;
int color[MAX*2<<2];//区间可见线段编号(颜色种类)
bool mark[MAX][MAX];//记录第i条线段和第j条线段可见
struct edge{
int y1,y2,x,id;
edge(){}
edge(int Y1,int Y2,int X,int ID):y1(Y1),y2(Y2),x(X),id(ID){}
bool operator <(const edge &a)const {
return x<a.x;
}
}s[MAX];
void Upchild(int n){
if(color[n]){
color[n<<1]=color[n<<1|1]=color[n];
color[n]=0;
}
}
void Update(int L,int R,int c,int n,int left,int right){
if(L<=left && right<=R){color[n]=c;return;}
Upchild(n);
int mid=left+right>>1;
if(L<=mid)Update(L,R,c,n<<1,left,mid);
if(R>mid)Update(L,R,c,n<<1|1,mid+1,right);
}
void Query(int L,int R,int id,int n,int left,int right){
if(color[n]){mark[id][color[n]]=true;return;}
if(left == right)return;
int mid=left+right>>1;
if(L<=mid)Query(L,R,id,n<<1,left,mid);
if(R>mid)Query(L,R,id,n<<1|1,mid+1,right);
}
int main(){
int t,n,y1,y2,x;
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;++i){
scanf("%d%d%d",&y1,&y2,&x);
s[i]=edge(y1,y2,x,i);
}
sort(s+1,s+n+1);
memset(color,0,sizeof color);
memset(mark,false,sizeof mark);
for(int i=1;i<=n;++i){
Query(s[i].y1*2,s[i].y2*2,s[i].id,1,0,MAX*2);//先查询这条线段左边可见的线段
Update(s[i].y1*2,s[i].y2*2,s[i].id,1,0,MAX*2);//更新该区间可见线段,放在Query里更新了
}
int ans=0;
for(int i=1;i<=n;++i){//暴力统计结果
for(int j=1;j<=n;++j){
if(mark[i][j])
for(int k=1;k<=n;++k){
if(mark[i][k] && mark[j][k])++ans;
}
}
}
printf("%d\n",ans);
}
return 0;
}

46
POJ/1745_non_cease.cpp Normal file
View File

@ -0,0 +1,46 @@
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#define N 10002
#define K 102
int num[N], n, k;
bool dp[N][K];
void Init()
{
int i;
scanf("%d%d", &n, &k);
for(i = 1; i <= n; i++)
scanf("%d", &num[i]);
}
bool Solve()
{
int i, j;
memset(dp, false, sizeof(dp));
dp[0][0] = true;
for(i = 1; i <= n; i++){
for(j = 0; j < k; j++){
if(dp[i-1][j]){
dp[i][abs(j + num[i]) % k] = true;
dp[i][abs(j - num[i]) % k] = true;
}
}
}
return dp[n][0];
}
int main()
{
Init();
if(Solve())
printf("Divisible\n");
else
printf("Not divisible\n");
return 0;
}

72
POJ/2528_wuyiqi.cpp Normal file
View File

@ -0,0 +1,72 @@
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL rt<<1
#define RR rt<<1|1
#define lson l,m,LL
#define rson m+1,r,RR
#define bug puts("bugbug");
const int maxn = 11111;
bool hash[10010];
int col[maxn<<4];
struct node{
int l,r;
}q[10010];
int ans;
int x[maxn<<2];
void pushdown(int rt){
if(col[rt]!=-1){
col[LL]=col[RR]=col[rt];
col[rt]=-1;
}
}
void update(int L,int R,int c,int l,int r,int rt){
if(L<=l&&r<=R){
col[rt]=c;
return ;
}
pushdown(rt);
int m=(l+r)>>1;
if(L<=m) update(L,R,c,lson);
if(R>m) update(L,R,c,rson);
}
void query(int l,int r,int rt){
if(col[rt]!=-1){
if(!hash[col[rt]]) ans++;
hash[col[rt]]=true;
return;
}
if(l==r) return;
int m=(l+r)>>1;
query(lson);
query(rson);
}
int main(){
int n,i,j,t;
scanf("%d",&t);
while(t--){
int cnt=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d%d",&q[i].l,&q[i].r);
x[cnt++]=q[i].l;x[cnt++]=q[i].r;
}
sort(x,x+cnt);
int m=1;
for(i=1;i<cnt;i++) if(x[i]!=x[i-1]) x[m++]=x[i];
for(i=m-1;i>=1;i--) if(x[i]!=x[i-1]+1) x[m++]=x[i-1]+1;
sort(x,x+m);
memset(col,-1,sizeof(col));
for(i=0;i<n;i++){
int l=lower_bound(x,x+m,q[i].l)-x;
int r=lower_bound(x,x+m,q[i].r)-x;
update(l,r,i,0,m,1);
}
memset(hash,false,sizeof(hash));
ans=0;
query(0,m,1);
printf("%d\n",ans);
}
return 0;
}

52
POJ/2828_ACMan.cpp Normal file
View File

@ -0,0 +1,52 @@
#include<stdio.h>
#include<string.h>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mid int m = (l + r)>>1
#define maxn 200000
int sum[maxn<<2],pos[maxn],val[maxn],ans[maxn<<2];//ans储存插入的值
void push_up(int rt)
{
sum [rt] = sum[rt<<1]+sum[rt<<1|1];
}
void build(int l, int r, int rt)
{
sum[rt]=r-l+1;
if(l == r)return;
mid;
build(lson);
build(rson);
}
void update(int pos, int val, int l, int r, int rt)
{
if(l == r){ans[rt]=val;sum[rt]--;return;}
mid;
if(pos <= sum[rt<<1])update(pos, val, lson); //根据左右儿子空位的多少和插入数据的位置比较来确定插入哪个儿子
else update(pos -sum[rt<<1], val, rson);
push_up(rt);
}
void print(int l, int r, int rt)
{
if(l == r){printf("%d ",ans[rt]);return;}
mid;
print(lson);
print(rson);
}
int main()
{
int n,i;
while(~scanf("%d",&n))
{
for(i=0;i<n;i++)
scanf("%d%d",&pos[i],&val[i]);
build(1, n ,1);
for(i=n-1;i>=0;i--)
update(pos[i]+1, val[i], 1, n, 1);
print(1, n, 1);
printf("\n");
}
return 0;
}

121
POJ/3225_niuox.cpp Normal file
View File

@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define Maxn 132000
//宏定义最好全加上括号
#define lx (x<<1)
#define rx ((x<<1) | 1)
#define MID ((l + r)>>1)
int cover[Maxn<<2];
int XOR[Maxn<<2];
bool vis[Maxn+5];
void FXOR(int x)
{
if(cover[x]!=-1) cover[x] ^= 1;
//注意是else
else XOR[x] ^= 1;
}
void pushDown(int x)
{
//cover[x] == -1代表x节点的覆盖工作已经结束
if(cover[x]!=-1)
{
cover[lx] = cover[rx] = cover[x];
XOR[lx] = XOR[rx] = 0;//既然已经覆盖异或标记就清零
cover[x] = -1;
}
if(XOR[x])
{
FXOR(lx);
FXOR(rx);
XOR[x] = 0;
}
}
void update(int L,int R,char op,int l,int r,int x)
{
if(L<=l && r<=R)
{
if(op == 'U')
{
cover[x] = 1;
XOR[x] = 0;
}
//op == 'I'的情况由于L<=l && r<=R所以不需要讨论
else if(op == 'D')
{
cover[x] = 0;
XOR[x] = 0;
}
else if(op == 'C') FXOR(x);
else if(op == 'S') FXOR(x);
return;
}
pushDown(x);
if(L<=MID) update(L,R,op,l,MID,lx);
else if(op == 'I' || op == 'C') cover[lx] = XOR[lx] = 0;
if(MID<R) update(L,R,op,MID+1,r,rx);
else if(op == 'I' || op == 'C') cover[rx] = XOR[rx] = 0;
}
//只适合于一次查询
void query(int l,int r,int x)
{
if(cover[x] == 1)
{
for(int i=l; i<=r; i++) vis[i] = true;
return;
}
else if(cover[x] == 0) return;
if(l == r) return;
pushDown(x);
query(l,MID,lx);
query(MID+1,r,rx);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int a,b;
char op,lchar,rchar;
XOR[1] = cover[1] = 0;
while(scanf("%c %c%d,%d%c\n",&op,&lchar,&a,&b,&rchar)!=EOF)
{
a<<=1;
b<<=1;
if(lchar == '(') a++;
if(rchar == ')') b--;
update(a,b,op,0,Maxn,1);
}
query(0,Maxn,1);
int s = -1,e;
bool flag = false;
for(int i=0;i<=Maxn;i++)
{
if(vis[i] == 1)
{
if(s == -1) s = i;
e = i;
}
else
{
if(s!=-1)
{
if(flag) printf(" ");
printf("%c%d,%d%c",s&1?'(':'[',s>>1,(e+1)>>1,e&1?')':']');
s = -1;
flag = true;
}
}
}
if(!flag) printf("empty set");
puts("");
return 0;
}

93
POJ/3468_acdreamers.cpp Normal file
View File

@ -0,0 +1,93 @@
#include <stdio.h>
#define N 111111
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
LL add[N<<2];
LL sum[N<<2];
void PushUP(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(int rt,int m)
{
if(add[rt])
{
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
sum[rt<<1]+=(m-(m>>1))*add[rt];
sum[rt<<1|1]+=(m>>1)*add[rt];
add[rt]=0;
}
}
void Build(int l,int r,int rt)
{
add[rt]=0;
if(l==r)
{
scanf("%I64d",&sum[rt]);
return;
}
int m=(l+r)>>1;
Build(lson);
Build(rson);
PushUP(rt);
}
void Update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
add[rt]+=c;
sum[rt]+=(LL)c*(r-l+1);
return;
}
PushDown(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m)
Update(L,R,c,lson);
if(R>m)
Update(L,R,c,rson);
PushUP(rt);
}
LL Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
return sum[rt];
PushDown(rt,r-l+1);
int m=(l+r)>>1;
LL ret=0;
if(L<=m) ret+=Query(L,R,lson);
if(R>m) ret+=Query(L,R,rson);
return ret;
}
int main()
{
int m,n;
scanf("%d%d",&n,&m);
Build(1,n,1);
while(m--)
{
char s[5];
int a,b,c;
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%d%d",&a,&b);
printf("%I64d\n",Query(a,b,1,n,1));
}
else
{
scanf("%d%d%d",&a,&b,&c);
Update(a,b,c,1,n,1);
}
}
return 0;
}