【热烈庆祝ZOJ回归】

P1002:简单的DFS

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ][];
 int N;

 int input()
 {
     scanf("%d",&N);
     ;i<N;i++) scanf("%s",map[i]);
     return N;
 }

 ][];

 ,sizeof(disable)); }

 int dfs(int cur)
 {
     )
         ][N-]>- || map[N-][N-]== : ;

     int c = cur / N;
     int r = cur % N;
     )
         );

     );
     for(int i=c;i<N && map[i][r]=='.';i++)
         ) disable[i][r]=cur;
     for(int j=r;j<N && map[c][j]=='.';j++)
         ) disable[c][j]=cur;

     res=std::max(res,dfs(cur+)+);

     for(int i=c;i<N && map[i][r]=='.';i++)
         ;
     for(int j=r;j<N && map[c][j]=='.';j++)
         ;

     return res;
 }
 //cur=N*c+r

 int main()
 {
     while(input())
     {
         init();
         printf());
     }
     ;
 }

Problem:ZOJ P1002

P1005:简单的DFSx2(Orz排行榜里那些28K的,我太弱所以用了1236K( ̄▽ ̄"))

另外不要吐槽人家丑陋的代码٩(×̯×)۶

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 int A,B,N;

 bool input()
 {
     return scanf("%d%d%d",&A,&B,&N)!=EOF;
 }

 ][];

 const char str_success[]="success";
 const char str_pour[]="pour";
 const char str_empty[]="empty";
 const char str_fill[]="fill";

 struct Cmd
 {
     const char* cmdType;
     char v1,v2;

     Cmd(const char* _cmd,char _v1,char _v2):
             cmdType(_cmd),v1(_v1),v2(_v2) {}

     void output()
     {
         if(cmdType==str_success) printf("%s\n",str_success);
         else if(cmdType==str_pour) printf("%s %c %c\n",str_pour,v1,v2);
         else if(cmdType==str_fill) printf("%s %c\n",str_fill,v1);
         else printf("%s %c\n",str_empty,v1);
     }
 };

 #include <stack>

 std::stack<Cmd> dfsStack;

 void init()
 {
     memset(ins,,sizeof(ins));
 }

 bool dfs(int a,int b)
 {
     ins[a][b]=true;
     if(b==N)
     {
         dfsStack.push(Cmd(str_success,'a','a'));
         return true;
     }

     ][b] && dfs(,b))
     {
         dfsStack.push(Cmd(str_empty,'A','A'));
         return true;
     }
     ] && dfs(a,))
     {
         dfsStack.push(Cmd(str_empty,'B','B'));
         return true;
     }
     if(a<A && !ins[A][b] && dfs(A,b))
     {
         dfsStack.push(Cmd(str_fill,'A','A'));
         return true;
     }
     if(b<B && !ins[a][B] && dfs(a,B))
     {
         dfsStack.push(Cmd(str_fill,'B','B'));
         return true;
     }

     int ra=A-a;
     int rb=B-b;
     if(a>=rb)
     {
         if(!ins[a-rb][B] && dfs(a-rb,B))
         {
             dfsStack.push(Cmd(str_pour,'A','B'));
             return true;
         }
     }
     else
     {
         ][a+b] && dfs(,a+b))
         {
             dfsStack.push(Cmd(str_pour,'A','B'));
             return true;
         }
     }
     if(b>=ra)
     {
         if(!ins[A][b-ra] && dfs(A,b-ra))
         {
             dfsStack.push(Cmd(str_pour,'B','A'));
             return true;
         }
     }
     else
     {
         ] && dfs(a+b,))
         {
             dfsStack.push(Cmd(str_pour,'B','A'));
             return true;
         }
     }

     return false;
 }

 void output()
 {
     while(!dfsStack.empty())
     {
         dfsStack.top().output();
         dfsStack.pop();
     }
 }

 int main()
 {
     while(input())
     {
         init();
         dfs(,);
         output();
     }
     ;
 }

Problem:ZOJ P1005

P1025:贪心

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 int s[maxN];
 int ans;

 #include <utility>

 typedef std::pair<int,int> Pr;

 Pr st[maxN];
 int N;

 void input()
 {
     scanf("%d",&N);
     ;i<=N;i++)
         scanf("%d%d",&st[i].first,&st[i].second);
 }

 int solve()
 {
     std::sort(st+,st+N+);
     ans=;
     ;i<=N;i++)
     {
         bool ok=false;
         ;j<=ans && !ok;j++)
             if(st[i].second>=s[j])
             {
                 s[j]=st[i].second;
                 ok=true;
             }
         if(!ok)
             s[++ans]=st[i].second;
     }
     return ans;
 }

 int main()
 {
     int cs; scanf("%d",&cs);
     while(cs--)
     {
         input();
         printf("%d\n",solve());
     }
     ;
 }

Problem:ZOJ P1025

P1074:裸的最大子矩阵

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 int v[maxN][maxN];
 int p[maxN][maxN]; //prefix
 int N;

 void input()
 {
     scanf("%d",&N);
     ;i<=N;i++)
         ;j<=N;j++)
             scanf("%d",v[i]+j);
 }

 void init()
 {
     ;j<=N;j++)
     {
         p[][j]=;
         p[][j]=v[][j];
         ;i<=N;i++)
             p[i][j]=p[i-][j]+v[i][j];
     }
 }

 int solve()
 {
     int ans=0x90000000;
     ;u<=N;u++)
         for(int d=u;d<=N;d++)
         {
             ;
             ;j<=N;j++)
             {
                 opt=opt<?(p[d][j]-p[u-][j]):opt+(p[d][j]-p[u-][j]);
                 ans=std::max(ans,opt);
             }
         }
     return ans;
 }

 int main()
 {
     input();
     init();
     printf("%d\n",solve());
     ;
 }

Problem:ZOJ P1074

P1093:DAG最长路,DP或者SPFA都可以解决

(代码君已死)

P1107:记忆化搜索(直接DP比较难写)

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 int opt[maxN][maxN];
 int val[maxN][maxN];
 int N,K;

 bool input()
 {
     scanf("%d%d",&N,&K);
     ) return false;
     ;i<N;i++)
         ;j<N;j++)
             scanf("%d",val[i]+j);
     return true;
 }

 void init()
 {
     memset(opt,,sizeof(opt));
 }

 int search(int hor,int ver)
 {
     if(opt[hor][ver]) return opt[hor][ver];
     ;u<=K && hor-u>=;u++)
         if(val[hor-u][ver]>val[hor][ver])
             opt[hor][ver]=std::max(opt[hor][ver],search(hor-u,ver));
     ;d<=K && hor+d<N;d++)
         if(val[hor+d][ver]>val[hor][ver])
             opt[hor][ver]=std::max(opt[hor][ver],search(hor+d,ver));
     ;l<=K && ver-l>=;l++)
         if(val[hor][ver-l]>val[hor][ver])
             opt[hor][ver]=std::max(opt[hor][ver],search(hor,ver-l));
     ;r<=K && ver+r<N;r++)
         if(val[hor][ver+r]>val[hor][ver])
             opt[hor][ver]=std::max(opt[hor][ver],search(hor,ver+r));
     opt[hor][ver]+=val[hor][ver];
     return opt[hor][ver];
 }

 int main()
 {
     while(input())
     {
         init();
         printf(,));
     }
     ;
 }

Problem:ZOJ P1107

P1108:LIS

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 struct Mouse
 {
     int weight;
     int speed;
     int idx;

     bool operator < (const Mouse& other) const
     {
         return this->weight > other.weight;
     }
 };

 Mouse ms[maxN];
 ;

 void input()
 {
     while(scanf("%d%d",&ms[N].weight,&ms[N].speed)!=EOF)
         { ms[N].idx=N; N++; }
     N--;
 }

 int dp[maxN];
 int last[maxN];

 void init()
 {
     ;i<=N;i++) dp[i]=;
     ;i<=N;i++) last[i]=i;
 }

 void solve()
 {
     init();
     ,mxn=;
     std::sort(ms+,ms+N+);
     ;i<=N;i++)
         ;j<i;j++)
             if(ms[j].weight>ms[i].weight && ms[j].speed<ms[i].speed)
             {
                 >dp[i])
                 {
                     dp[i]=dp[j]+;
                     last[i]=j;
                     if(dp[i]>mx)
                     {
                         mx=dp[i];
                         mxn=i;
                     }
                 }
             }
     printf("%d\n",mx);
     while(last[mxn]!=mxn)
     {
         printf("%d\n",ms[mxn].idx);
         mxn=last[mxn];
     }
     printf("%d\n",ms[mxn].idx);
 }

 int main()
 {
     input();
     solve();
     ;
 }

Problem:ZOJ P1108

P1149:很裸的多重背包(一开始居然没发现,果然自己弱爆了……)

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 ;

 const char* success="Can be divided.";
 const char* fail="Can't be divided.";
 const char* tpl="Collection #%d:\n%s\n\n";

 int dp[maxV];

 int N;
 int v[maxN];

 void init()
 {
     memset(dp,,sizeof(dp));
     N=;
 }

 ];

 ;

 bool proc()
 {
     ;i<=;i++) scanf("%d",cnt+i);
     bool end=true;
     ;i<=;i++) if(cnt[i]) { end=false; break; }
     if(end) return false;
     ;
     ;i<=;i++) sum+=cnt[i]*i;
     )
     {
         printf(tpl,++cs,fail);
         return true;
     }
     sum>>=;
     init();
     ;i<=;i++)
     {
         ;
         while(x<=cnt[i])
         {
             v[++N]=x*i;
             cnt[i]-=x;
             x<<=;
         }
         if(cnt[i]) v[++N]=cnt[i]*i;
     }
     ;i<=N;i++)
         for(int j=sum;j>=v[i];j--)
             dp[j]=std::max(dp[j],dp[j-v[i]]+v[i]);
     printf(tpl,++cs,dp[sum]==sum?success:fail);
     return true;
 }

 int main()
 {
     while(proc());
     ;
 }

Problem:ZOJ P1149

由于只需判定可行性,所以此题的dp数组可以用bool代替,初值为dp[0]=true

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 ;

 const char* success="Can be divided.";
 const char* fail="Can't be divided.";
 const char* tpl="Collection #%d:\n%s\n\n";

 bool dp[maxV];

 int N;
 int v[maxN];

 void init()
 {
     memset(dp,,sizeof(dp));
     N=;
 }

 ];

 ;

 bool proc()
 {
     ;i<=;i++) scanf("%d",cnt+i);
     bool end=true;
     ;i<=;i++) if(cnt[i]) { end=false; break; }
     if(end) return false;
     ;
     ;i<=;i++) sum+=cnt[i]*i;
     )
     {
         printf(tpl,++cs,fail);
         return true;
     }
     sum>>=;
     init();
     ;i<=;i++)
     {
         ;
         while(x<=cnt[i])
         {
             v[++N]=x*i;
             cnt[i]-=x;
             x<<=;
         }
         if(cnt[i]) v[++N]=cnt[i]*i;
     }
     dp[]=true;
     ;i<=N;i++)
         for(int j=sum;j>=v[i];j--)
             dp[j]|=dp[j-v[i]];
     printf(tpl,++cs,dp[sum]?success:fail);
     return true;
 }

 int main()
 {
     while(proc());
     ;
 }

Problem:ZOJ P1149(Optimized)

P1196:DP,dp[x][y]表示前x个餐馆处设置第y个depot,其之前部分的最小代价。代码中使用滚动数组压缩掉了第2维

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 ;
 const int inf=0x3f3f3f3f;

 int dp[maxN];
 int dist[maxN];
 int N,K;

 bool input()
 {
     scanf("%d%d",&N,&K);
     if(!N) return false;
     ;i<=N;i++) scanf("%d",dist+i);
     dist[N+]=inf;
     dist[]=-inf;
     return true;
 }

 int gap[maxN][maxN];

 void initGap()
 {
     memset(gap,,sizeof(gap));
     ;i<N;i++)
         ;j<=N+;j++)
             ;k<j;k++)
                 gap[i][j]+=std::min(dist[j]-dist[k],dist[k]-dist[i]);
 }

 int solve()
 {
     memset(dp,0x3f,sizeof(dp));
     for(int i=N;i;i--)
         dp[i]=gap[][i];
     ;t<=K;t++)
     {
         for(int i=N;i>=t;i--)
             ;j>=;j--)
                 dp[i]=std::min(dp[i],dp[j]+gap[j][i]);
     }
     int ans=inf;
     for(int i=K;i<=N;i++)
         ans=std::min(ans,dp[i]+gap[i][N+]);
     return ans;
 }

 ;
 int main()
 {
     while(input())
     {
         initGap();
         printf("Chain %d\nTotal distance sum = %d\n\n",++cs,solve());
     }
     ;
 }

Problem:ZOJ P1196

P1440:置换数+逆序对

如果代码中加一句#undef TEST,我们实际上就对val进行了离散化(比一般的排序+lower_bound要高效一些)

此外需要注意一下数据范围,逆序对数可能爆int

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 int val[maxN];
 int pos[maxN];
 bool vis[maxN];
 int N;

 void input()
 {
     scanf("%d",&N);
     ;i<=N;i++)
     {
         scanf("%d",val+i);
         pos[i]=i;
     }
 }

 inline bool cmp(int x,int y)
 {
     return val[x] < val[y];
 }

 inline void swap(int* x,int* y)
 {
     int t=*x; *x=*y; *y=t;
 }

 #define TEST

 int getMinSwapCnt()
 {
     std::sort(pos+,pos+N+,cmp);
     memset(vis,,sizeof(vis));
 #ifndef TEST
     ;i<=N;i++) val[pos[i]]=i;
 #endif
     ;
     ;i<=N;i++)
         if(!vis[i])
         {
 #ifndef TEST
             for(int j=i;!vis[j];j=val[j]) vis[j]=true;
 #else
             for(int j=i;!vis[j];j=pos[j]) vis[j]=true;
 #endif
             ++res;
         }
     return N-res;
 }

 typedef long long int64;

 int64 mergeSort_aux(int left,int right)
 {
     ;
     ==right)
     {
         ;
         ; }
     }
     ;
     int64 res=mergeSort_aux(left,mid)+mergeSort_aux(mid+,right);
     ;
     int p=left;
     while(i<=mid && j<=right)
     {
         if(val[i]<val[j]) pos[p++]=val[i++];
         else
         {
             pos[p++]=val[j++];
             res+=(mid+-i);
         }
     }
     for(;i<=mid;i++) pos[p++]=val[i];
     for(;j<=right;j++) pos[p++]=val[j];
     memcpy(val+left,pos+left,(right-left+)*sizeof(int));
     return res;
 }

 int64 getInvPairCnt()
 {
     ,N);
 }

 #include <iostream>

 int main()
 {
     input();
     std::cout<<getMinSwapCnt()<<"\n";
     std::cout<<getInvPairCnt()<<"\n";
     ;
 }

Problem:ZOJ P1440

P1985:单调栈

 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 #include <iostream>

 ;

 int h[maxN];
 int l[maxN],r[maxN];
 int s[maxN],p;
 int N;

 bool input()
 {
     scanf("%d",&N);
     if(!N) return false;
     ;i<N;i++) scanf("%d",h+i);
     return true;
 }

 typedef long long int64;

 int64 solve()
 {
     p=-;
     ;i<N;i++)
     {
          && h[s[p]]>=h[i];p--);
         l[i]=(p==-)?:s[p]+;
         s[++p]=i;
     }
     p=-;
     ;i--)
     {
          && h[s[p]]>=h[i];p--);
         r[i]=(p==-)?N:s[p];
         s[++p]=i;
     }
     int64 ans();
     ;i<N;i++)
         ans=std::max(ans,int64(h[i])*(r[i]-l[i]));
     return ans;
 }

 int main()
 {
     while(input()) std::cout<<solve()<<"\n";
     ;
 }

Problem:ZOJ P1985

P2112:树套树或者平方分割均可

详见:http://www.cnblogs.com/Onlynagesha/p/5355133.html

 template <class T>
 struct SbtNode
 {
     typedef SbtNode<T> Node;
     Node* lch;
     Node* rch;

     T val;
     int lSize;
     int rSize;

     SbtNode(const T& _val):
             lch(),rch(),val(_val),lSize(),rSize() {}
     void assign(const T& _val)
     {
         lch=rch=;
         val=_val;
         lSize=rSize=;
     }
 };

 template <class T,class Comp>
 struct SizeBlcTree
 {
     ,Left=,Right= };
     typedef SbtNode<T> Node;
     typedef SizeBlcTree<T,Comp> Sbt;

     Node* root;
     Comp cmp;

     SizeBlcTree():root() {}
     ~SizeBlcTree() { clear(); }

     void clear_aux(Node* _cur)
     {
         if(_cur->lch) clear_aux(_cur->lch);
         if(_cur->rch) clear_aux(_cur->rch);
         delete _cur;
     }

     void clear()
     {
         if(root) clear_aux(root);
         root=;
     }

     Node* lRotate(Node* _cur)
     {
         Node* next=_cur->rch;
         _cur->rch=next->lch;
         next->lch=_cur;

         _cur->rSize=next->lSize;
         next->lSize+=(_cur->lSize+);

         return next;
     }

     Node* rRotate(Node* _cur)
     {
         Node* next=_cur->lch;
         _cur->lch=next->rch;
         next->rch=_cur;

         _cur->lSize=next->rSize;
         next->rSize+=(_cur->rSize+);

         return next;
     }

     Node* insert_aux(const T& _val,Node* _cur)
     {
         if(!_cur) return new Node(_val);

         if(cmp(_val,_cur->val))
         {
             ++_cur->lSize;
             _cur->lch=insert_aux(_val,_cur->lch);
             if(_cur->lch->lSize > _cur->rSize) return rRotate(_cur);
             else if(_cur->lch->rSize > _cur->rSize)
             {
                 _cur->lch=lRotate(_cur->lch);
                 return rRotate(_cur);
             }
             else return _cur;
         }
         else
         {
             ++_cur->rSize;
             _cur->rch=insert_aux(_val,_cur->rch);
             if(_cur->rch->rSize > _cur->lSize) return lRotate(_cur);
             else if(_cur->rch->lSize > _cur->lSize)
             {
                 _cur->rch=rRotate(_cur->rch);
                 return lRotate(_cur);
             }
             else return _cur;
         }
     }

     Sbt& operator << (const T& _val)
     {
         root=insert_aux(_val,root);
         return *this;
     }

     Node* erase_aux(const T& _val,Node* _cur,bool& _found)
     {
         if(!_cur)
         {
             _found=false;
             ;
         }
         if(cmp(_val,_cur->val))
         {
             _cur->lch=erase_aux(_val,_cur->lch,_found);
             if(_found) --_cur->lSize;
             return _cur;
         }
         if(cmp(_cur->val,_val))
         {
             _cur->rch=erase_aux(_val,_cur->rch,_found);
             if(_found) --_cur->rSize;
             return _cur;
         }

         _found=true;
         ;
         ;
         ;
         Node* res;
         Node* &prev=res;

         switch(status)
         {
         :
             delete _cur;
             ;
         :
             res=_cur->lch;
             delete _cur;
             return res;
         :
             res=_cur->rch;
             delete _cur;
             return res;
         :
             prev=_cur;
             if(prev->rch->lch)
             {
                 --prev->rSize;
                 prev=prev->rch;

                 while(prev->lch->lch)
                 {
                     --prev->lSize;
                     prev=prev->lch;
                 }
                 _cur->val=prev->lch->val;
                 prev->lch=erase_aux(prev->lch->val,prev->lch,_found);
                 --prev->lSize;
             }
             else
             {
                 _cur->val=_cur->rch->val;
                 _cur->rch=erase_aux(_cur->rch->val,_cur->rch,_found);
                 --_cur->rSize;
             }
             return _cur;
         }
     }

     Sbt& operator >> (const T& _val)
     {
         bool found=false;
         root=erase_aux(_val,root,found);
         return *this;
     }

     int notMoreCount(const T& _val)
     {
         Node* cur=root;
         ;
         while(cur)
         {
             if(cmp(_val,cur->val)) cur=cur->lch;
             else
             {
                 res+=(cur->lSize+);
                 cur=cur->rch;
             }
         }
         return res;
     }

     int lessCount(const T& _val)
     {
         Node* cur=root;
         ;
         while(cur)
         {
             if(cmp(cur->val,_val))
             {
                 res+=(cur->lSize+);
                 cur=cur->rch;
             }
             else cur=cur->lch;
         }
         return res;
     }
 };

 ;
 ;
 ;
 ;

 #include <functional>
 #include <algorithm>

 int unOrd[bktCount*bktSize];

 using std::less;
 SizeBlcTree<int,less<int> > all;
 SizeBlcTree<int,less<int> > bucket[bktCount];
 int N,K;
 int cs;

 #include <cstdio>

 void init()
 {
     scanf("%d%d",&N,&K);
     ;i<N;i++)
     {
         scanf("%d",unOrd+i);
         all<<unOrd[i];
         bucket[i>>bktDigit] << unOrd[i];
     }
 }

 inline void enumerate(int _rL,int _rR,int _val,int& _less,int& _notMore)
 {
     for(int i=_rL;i<=_rR;i++) if(unOrd[i]<=_val)
     {
         _notMore++;
         if(unOrd[i]<_val) _less++;
     }
 }

 int getAns(int _rL,int _rR,int _k)
 {
     int bktL = _rL>>bktDigit;
     int bktR = _rR>>bktDigit;

     int prevVal;
     SbtNode<int> *cur=all.root;
     while(cur)
     {
         ;
         ;
         if(bktL==bktR) enumerate(_rL,_rR,cur->val,less,notMore);
         else
         {
             ;i<bktR;i++)
             {
                 notMore += bucket[i].notMoreCount(cur->val);
                 less += bucket[i].lessCount(cur->val);
             }
             enumerate(_rL,((bktL+)<<bktDigit)-,cur->val,less,notMore);
             enumerate(bktR<<bktDigit,_rR,cur->val,less,notMore);
         }
         if(less<_k && notMore>=_k) return cur->val;
         prevVal=cur->val;
         if(less>=_k) cur=cur->lch;
         else cur=cur->rch;
     }
     return prevVal;
 }

 void solve()
 {
     char cmd;
     do cmd=getchar(); while(cmd==' ' || cmd=='\n');
     if(cmd=='Q')
     {
         int rL,rR,k;
         scanf("%d%d%d",&rL,&rR,&k);
         printf(,rR-,k));
     }
     else
     {
         int pos,v;
         scanf("%d%d",&pos,&v);
         --pos;
         all<<v;
         bucket[pos>>bktDigit] >> unOrd[pos];
         bucket[pos>>bktDigit] << (unOrd[pos]=v) ;
     }
 }

 void reset()
 {
     all.clear();
     int used=N>>bktDigit;
     ;i<=used;i++) bucket[i].clear();
 }

 int main()
 {
     scanf("%d",&cs);
     while(cs--)
     {
         init();
         while(K--) solve();
         reset();
     }
     ;
 }

Problem:ZOJ P2112

P2114:LCTdf好!!!

人生第一棵Link-cut-tree

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ,Right= };

 struct SplayNode;
 SplayNode* vir;

 struct SplayNode
 {
     int dist;
     int totDist;
     bool isRoot;
     SplayNode* parent;
     SplayNode* child[];

     void init()
     {
         dist=totDist=;
         isRoot=true;
         parent=child[]=child[]=vir;
     }

     void clear()
     {
         if(child[Left]!=vir) child[Left]->clear();
         if(child[Right]!=vir) child[Right]->clear();
         delete this;
     }

     void update()
     {
         this->totDist =
                 child[Left]->totDist+child[Right]->totDist+this->dist;
     }

     void rotate(int dir)
     //If dir==Right then rotate clockwise, else rotate counter-clockwise
     {
         if(parent==parent->parent->child[Left])
             parent->parent->child[Left]=this;
         else if(parent==parent->parent->child[Right])
             parent->parent->child[Right]=this;

         parent->child[dir^]=this->child[dir];
         child[dir]->parent=this->parent;

         child[dir]=parent;
         parent=parent->parent;
         child[dir]->parent=this;
     }

     void zigzig(int dir)
     {
         parent->rotate(dir);
         this->rotate(dir);

         child[dir]->child[dir]->update();
         child[dir]->update();
         this->update();
     }

     void zigzag(int dir) //dir depends on first rotation
     {
         rotate(dir);
         rotate(dir^);

         child[Left]->update();
         child[Right]->update();
         this->update();
     }

     void zig(int dir)
     {
         rotate(dir);
         child[dir]->update();
         this->update();
     }

     void splay()
     {
         while(!isRoot)
         {
             ;
             ;
             ;

             if(!parent->isRoot)
             {
                 if(parent->parent->isRoot) this->isRoot=true;
                 ;
                 ;
             }
             else
                 this->isRoot=true;

             switch(status)
             {
             : zig(Right);
                     child[Right]->isRoot=false;
                     break;
             : zig(Left);
                     child[Left]->isRoot=false;
                     break;
             : zigzig(Right);
                     if(isRoot) child[Right]->child[Right]->isRoot=false;
                     break;
             : zigzag(Left);
                     if(isRoot) child[Right]->isRoot=false;
                     break;
             : zigzag(Right);
                     if(isRoot) child[Left]->isRoot=false;
                     break;
             :zigzig(Left);
                     if(isRoot) child[Left]->child[Left]->isRoot=false;
                     break;
             default:break;
             }
         }
     }
 };

 int access(SplayNode* u)
 {
     SplayNode* v=vir;
     ;
     while(u!=vir)
     {
         u->splay();
         u->child[Right]->isRoot=true;
         res=u->child[Right]->totDist;
         u->child[Right]=v;
         v->isRoot=false;
         u->update();
         v=u; u=u->parent;
     }
     return res + v->child[Right]->totDist;
 }

 inline int query(SplayNode* u,SplayNode* v)
 {
     access(u);
     return access(v);
 }

 void initVir()
 {
     vir=new SplayNode;
     vir->init();
 }

 ;

 SplayNode node[maxN];
 int center[maxN];
 int N,Q;
 ;

 inline void link(int u,int v,int len)
 {
     access(node+u);
     node[u].splay();
     center[u]=v;
     node[u].parent=node+v;
     node[u].dist=len;
     node[u].update();
 }

 inline void initNode()
 {
     ;i<=N;i++) node[i].init();
     ;i<=N;i++) center[i]=i;
 }

 int getCenter(int x)
 {
     return center[x]==x ? x :
            center[x]=getCenter(center[x]);
 }

 #define DEBUG
 #undef DEBUG

 #ifdef DEBUG
 ;
 #endif

 void solve()
 {
     lastRes=;
     scanf("%d%d",&N,&Q);
     initNode();
     char cmd;
     int v1,v2,len;
     while(Q--)
     {
         do cmd=getchar(); while(cmd==' ' || cmd=='\n');
         if(cmd=='Q')
         {
             scanf("%d%d",&v1,&v2);
             if(getCenter(v1)==getCenter(v2))
                 printf("%d\n",lastRes=query(node+v1,node+v2));
             else printf("Not connected.\n");
 #ifdef DEBUG
             printf("#%d query successful.\n",++qc);
 #endif
         }
         else
         {
             scanf("%d%d%d",&v1,&v2,&len);
 #ifndef DEBUG
             v1=(v1-lastRes-)%N;
             ) v1+=N;
             v2=(v2-lastRes-)%N;
             ) v2+=N;
 #endif
             link(getCenter(v1),getCenter(v2),len);
         }
     }
 }

 int main()
 {
     //freopen("/home/onlynagesha/Desktop/a.in","r",stdin);
     //freopen("t.out","w",stdout);

     initVir();
     int X; scanf("%d",&X);
     while(X--) solve();
     ;
 }

Problem:ZOJ P2114

P2334:左偏树+并查集

详见:http://www.cnblogs.com/Onlynagesha/p/5406403.html

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 template <class T>
 struct HeapNode
 {
     typedef HeapNode<T> Node;
     Node* lch;
     Node* rch;
     T val;
     int dist;

     HeapNode(),rch(),val(_val),dist() {}

     void clear()
     {
         if(lch) lch->clear();
         if(rch) rch->clear();
         delete this;
     }
 };

 template <class T,class Comp>
 struct LeftistHeap
 {
     typedef HeapNode<T> Node;
     typedef LeftistHeap<T,Comp> Heap;

     Node* root;
     Comp cmp;

     LeftistHeap():root() {}
     ~LeftistHeap()
     {
         clear();
     }

     void clear()
     {
         if(root) root->clear();
         root=;
     }

     Node* merge(Node* A,Node* B)
     {
         if(!A) return B;
         if(!B) return A;

         if(cmp(B->val,A->val)) std::swap(A,B);
         A->rch=merge(B,A->rch);

         if(!A->lch || A->rch->dist > A->lch->dist)
             std::swap(A->lch,A->rch);
         A->dist = (A->rch) ? A->rch->dist +  :  ;

         return A;
     }

     void push(const T& _val)
     {
         Node* nNode=new Node(_val);
         root=merge(root,nNode);
     }

     Heap& operator << (const T& _val)
     {
         push(_val);
         return *this;
     }

     T top()
     {
         return root->val;
     }

     void pop()
     {
         Node* temp=root;
         root=merge(temp->lch,temp->rch);
         delete temp;
     }

     Heap& operator >> (T& _dest)
     {
         _dest=top();
         pop();
         return *this;
     }

     void merge(Heap& _other)
     {
         this->root=merge(this->root,_other.root);
         _other.root=;
     }

     bool empty()
     {
         ;
     }
 };

 #include <functional>

 ;

 int N,M;
 int idx[maxN];

 int father(int x)
 {
     return idx[x]==x ? x : idx[x]=father(idx[x]) ;
 }

 LeftistHeap<int,std::greater<int> > heap[maxN];

 void init()
 {
     ;i<maxN;i++) heap[i].clear();
     ;i<maxN;i++) idx[i]=i;
 }

 bool solve()
 {
     init();

     if(scanf("%d",&N)==EOF) return false;
     ;i<=N;i++)
     {
         int s; scanf("%d",&s);
         heap[i].push(s);
     }

     scanf("%d\n",&M);
     while(M--)
     {
         int mk1,mk2;
         scanf("%d%d",&mk1,&mk2);

         int f1=father(mk1);
         int f2=father(mk2);
         if(f1==f2)
         {
             printf("-1\n");
             continue;
         }

         int s1,s2;
         heap[f1]>>s1;
         heap[f2]>>s2;

         if(f1<f2)
         {
             idx[f2]=f1;
             heap[f1].merge(heap[f2]);
             );
             ));
             heap[f1] << (s1>>) << (s2>>);
         }
         else
         {
             idx[f1]=f2;
             heap[f2].merge(heap[f1]);
             );
             ));
             heap[f2] << (s1>>) << (s2>>);
         }
     }

     return true;
 }

 int main()
 {
     while(solve());
     ;
 }

Problem:ZOJ P2334

P2592:有一个非常神奇的性质

 #include <cstdio>

 int main()
 {
     int N,T;
     scanf("%d",&T);
     while(T--)
     {
         scanf("%d",&N);
         ;
         ;i<N;i++)
         {
             int v;
             scanf("%d",&v);
             tot+=v;
         }
         printf(?tot:);
     }
     ;
 }

Problem:ZOJ P2592

然而偶的思路就有些繁琐了,而且套了个SBT模板(参考:http://www.cnblogs.com/Onlynagesha/p/5350398.html)

基本思想是维护前缀和序列,在序列“移动”过程中设立了一个offset变量,相当于给整棵树打了一个LazyTag

类似的思想可用于NOI2005“郁闷的出纳员”一题

 template <class T>
 struct SbtNode
 {
     typedef SbtNode<T> Node;
     Node* lch;
     Node* rch;

     T val;
     int lSize;
     int rSize;

     SbtNode(const T& _val):
             lch(),rch(),val(_val),lSize(),rSize() {}
     void assign(const T& _val)
     {
         lch=rch=;
         val=_val;
         lSize=rSize=;
     }
 };

 template <class T,class Comp>
 struct SizeBlcTree
 {
     ,Left=,Right= };
     typedef SbtNode<T> Node;
     typedef SizeBlcTree<T,Comp> Sbt;

     Node* root;
     Comp cmp;

     SizeBlcTree():root() {}
     ~SizeBlcTree() { clear(); }

     void clear_aux(Node* _cur)
     {
         if(_cur->lch) clear_aux(_cur->lch);
         if(_cur->rch) clear_aux(_cur->rch);
         delete _cur;
     }

     void clear()
     {
         if(root) clear_aux(root);
         root=;
     }

     Node* lRotate(Node* _cur)
     {
         Node* next=_cur->rch;
         _cur->rch=next->lch;
         next->lch=_cur;

         _cur->rSize=next->lSize;
         next->lSize+=(_cur->lSize+);

         return next;
     }

     Node* rRotate(Node* _cur)
     {
         Node* next=_cur->lch;
         _cur->lch=next->rch;
         next->rch=_cur;

         _cur->lSize=next->rSize;
         next->rSize+=(_cur->rSize+);

         return next;
     }

     Node* insert_aux(const T& _val,Node* _cur)
     {
         if(!_cur) return new Node(_val);

         if(cmp(_val,_cur->val))
         {
             ++_cur->lSize;
             _cur->lch=insert_aux(_val,_cur->lch);
             if(_cur->lch->lSize > _cur->rSize) return rRotate(_cur);
             else if(_cur->lch->rSize > _cur->rSize)
             {
                 _cur->lch=lRotate(_cur->lch);
                 return rRotate(_cur);
             }
             else return _cur;
         }
         else
         {
             ++_cur->rSize;
             _cur->rch=insert_aux(_val,_cur->rch);
             if(_cur->rch->rSize > _cur->lSize) return lRotate(_cur);
             else if(_cur->rch->lSize > _cur->lSize)
             {
                 _cur->rch=rRotate(_cur->rch);
                 return lRotate(_cur);
             }
             else return _cur;
         }
     }

     Sbt& operator << (const T& _val)
     {
         root=insert_aux(_val,root);
         return *this;
     }

     Node* erase_aux(const T& _val,Node* _cur,bool& _found)
     {
         if(!_cur)
         {
             _found=false;
             ;
         }
         if(cmp(_val,_cur->val))
         {
             _cur->lch=erase_aux(_val,_cur->lch,_found);
             if(_found) --_cur->lSize;
             return _cur;
         }
         if(cmp(_cur->val,_val))
         {
             _cur->rch=erase_aux(_val,_cur->rch,_found);
             if(_found) --_cur->rSize;
             return _cur;
         }

         _found=true;
         ;
         ;
         ;
         Node* res;
         Node* &prev=res;

         switch(status)
         {
         :
             delete _cur;
             ;
         :
             res=_cur->lch;
             delete _cur;
             return res;
         :
             res=_cur->rch;
             delete _cur;
             return res;
         :
             prev=_cur;
             if(prev->rch->lch)
             {
                 --prev->rSize;
                 prev=prev->rch;

                 while(prev->lch->lch)
                 {
                     --prev->lSize;
                     prev=prev->lch;
                 }
                 _cur->val=prev->lch->val;
                 prev->lch=erase_aux(prev->lch->val,prev->lch,_found);
                 --prev->lSize;
             }
             else
             {
                 _cur->val=_cur->rch->val;
                 _cur->rch=erase_aux(_cur->rch->val,_cur->rch,_found);
                 --_cur->rSize;
             }
             return _cur;
         }
     }

     Sbt& operator >> (const T& _val)
     {
         bool found=false;
         root=erase_aux(_val,root,found);
         return *this;
     }

     T min()
     {
         Node* cur=root;
         while(cur->lch) cur=cur->lch;
         return cur->val;
     }
 };

 ;

 int T,N;
 int offset;
 int arr[maxN];
 int prefix[maxN];

 #include <functional>
 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 SizeBlcTree<int,std::less<int> > sbt;

 void init()
 {
     offset=;
     prefix[]=;
     sbt.clear();
 }

 int solve()
 {
     init();

     scanf("%d",&N);
     ;i<=N;i++)
     {
         scanf("%d",arr+i);
         prefix[i]=prefix[i-]+arr[i];
         sbt<<prefix[i];
     }

      ?  :  ;
     prefix[]=prefix[N];

     ;i<N;i++)
     {
         offset-=arr[i];
         sbt>>prefix[i];
         prefix[i]=prefix[i-]+arr[i];
         sbt<<prefix[i];

         ) ++ans;
     }

     return ans;
 }

 int main()
 {
     scanf("%d",&T);
     while(T--) printf("%d\n",solve());
     ;
 }

Another Solution to ZOJ P2592

P2652:只需分两种情况:改变第一行或不改变第一行。此后所有的状态都可以推导出来,无需再进行枚举

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 ;

 int mat[maxN][maxN];
 int N,M;

 bool input()
 {
     if(scanf("%d%d",&M,&N)==EOF) return false;
     ;i<=M;i++)
         ;j<=N;j++)
             scanf("%d",mat[i]+j);
     return true;
 }

 bool ch[maxN];

 int check()
 {
     ;
     memset(ch,,sizeof(ch));
     ;i<=N;i++)
         ][i]<) { ch[i]=true; ++res; }
     ;i<=N;i++)
         ;j<=M;j++)
             mat[j][i]=-mat[j][i];
     ;j<=M;j++)
     {
         ;;
         ;i<=N;i++)
             ) ++c;
         if(c==N) ++res;
         else if(c) { res=inf; break; }
     }
     ;i<=N;i++)
         ;j<=M;j++)
             mat[j][i]=-mat[j][i];
     return res;
 }

 int solve()
 {
     int ans=check();
     ;i<=N;i++) mat[][i]=-mat[][i];
     ans=std::min(ans,+check());
     :ans;
 }

 int main()
 {
     while(input())
         printf("%d\n",solve());
     ;
 }

Problem:ZOJ P2652

P2671:线段树

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 int N,M,R;
 );

 struct Mat
 {
     ][];

     Mat() { memset(v,,sizeof(v)); }

     Mat operator * (const Mat& u) const
     {
         Mat a;
         ;i<;i++)
             ;j<;j++)
             {
                 ;k<;k++)
                     a.v[i][j]+=this->v[i][k]*u.v[k][j];
                 a.v[i][j]%=R;
             }
         return a;
     }

     void read()
     {
         scanf(],v[]+,v[],v[]+);
     }

     void print()
     {
         ) printf("\n");
         printf(][],v[][],v[][],v[][]);
     }
 };

 Mat mt[maxN];

 struct SegTree
 {
     Mat* node;
     int size;

     SegTree(*size+]; }
     ~SegTree() { delete[] node; }

     template <class RAIter>
     void init_aux(RAIter begin,int len,int cur)
     {
         ) {
             node[cur]=*begin; return;
         }
         );
         init_aux(begin,len>>,cur+);
         init_aux(begin+(len>>),(len+)>>,rt);
         node[cur]=node[cur+]*node[rt];
     }

     template <class RAIter>
     void init(RAIter begin)
     {
         init_aux(begin,size,);
     }

     Mat ask_aux(int rl,int rr,int nl,int nr,int cur)
     {
         if(rl<=nl && rr>=nr) return node[cur];
         ;
         );
         );
         else if(rl>=mid) return ask_aux(rl,rr,mid,nr,rt);
         )*ask_aux(rl,rr,mid,nr,rt);
     }

     Mat ask(int l,int r)
     {
         ,size,);
     }
 };

 bool input()
 {
     if(scanf("%d%d%d",&R,&N,&M)==EOF) return false;
     ;i<=N;i++)
         mt[i].read();
     return true;
 }

 void proc()
 {
     SegTree tree(N);
     tree.init(mt+);
     int l,r;
     Mat ans;
     while(M--)
     {
         scanf("%d%d",&l,&r);
         ans=tree.ask(l-,r);
         ans.print();
     }
 }

 int main()
 {
     );
     while(input())
         proc();
     ;
 }

Problem:ZOJ P2671

P2688:很有意思的题目,题解参考:http://blog.csdn.net/axuan_k/article/details/47447281

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 ;

 double v[maxK][maxN];
 int N;

 bool input()
 {
     scanf("%d",&N);
     if(!N) return false;
     ];
     ;f<=N;f++)
     {
         ;i<;i++)
             scanf("%lf",a+i);
         ;b<;b++)
         {
             v[b][f]=0.0;
             ,j=b;i<;i++,j>>=)
             {
                 ) v[b][f]+=a[i];
                 else v[b][f]-=a[i];
             }
         }
     }
     return true;
 }

 double solve()
 {
     double mx,mn;
     double ans(-1e100);
     ;b<;b++)
     {
         mx=-1e100; mn=1e100;
         ;i<=N;i++)
         {
             mx=std::max(mx,v[b][i]);
             mn=std::min(mn,v[b][i]);
         }
         ans=std::max(ans,mx-mn);
     }
     return ans;
 }

 int main()
 {
     while(input())
         printf("%.2lf\n",solve());
     ;
 }

Problem:ZOJ P2688

P3164:背包问题的加强版,输入及其恶心,代码也很丑……(/= _ =)/~┴┴

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 int N,D;
 int K[maxN],E[maxN],P[maxN];
 int G;
 int inGrp[maxN];

 char buf[maxN];

 void procGrp(int idx)
 {
     ;
     ;;i++)
     {
         if(buf[i]=='\n' || buf[i]=='\0')
         {
             if(v) inGrp[v]=idx;
             break;
         }
         else if(buf[i]==' ')
             { inGrp[v]=idx; v=; }
         else
             { v*=; v+=(buf[i]-'); }
     }
 }

 bool input()
 {
     if(scanf("%d%d",&N,&D)==EOF)
         return false;
     ;i<=N;i++)
     {
         scanf("%d%d%d",K+i,E+i,P+i);
         if(!K[i]) K[i]=D/P[i];
     }
     scanf("%d",&G);
     memset(inGrp,-,sizeof(inGrp));
     fgets(buf,maxN,stdin);
     ;i<G;i++)
     {
         fgets(buf,maxN,stdin);
         procGrp(i);
     }
     return true;
 }

 ][maxN];
 int dp[maxN];

 int solve()
 {
     memset(grpOpt,0xc0,sizeof(grpOpt));
     ;i<;i++) grpOpt[i][]=;
     memset(dp,]=;
     ;i<=N;i++)
         )
         {
             int& grp=inGrp[i];
             ;j<=K[i] && j*P[i]<=D;j++)
                 grpOpt[grp][j*P[i]]=std::max
                         (grpOpt[grp][j*P[i]],j*E[i]);
         }
     ;i<=N;i++)
         )
         {
             int k=K[i];
             ;j<=k;j<<=)
             {
                 k-=j;
                 for(int v=D;v>=P[i]*j;v--)
                     dp[v]=std::max(dp[v],dp[v-P[i]*j]+E[i]*j);
             }
             if(k) for(int v=D;v>=P[i]*k;v--)
                 dp[v]=std::max(dp[v],dp[v-P[i]*k]+E[i]*k);
         }
     ;i<G;i++)
         for(int v=D;v;v--)
             for(int w=v;w;w--)
                 dp[v]=std::max(dp[v],dp[v-w]+grpOpt[i][w]);
     return dp[D];
 }

 int main()
 {
     while(input())
     {
         int ans=solve();
         ) printf("i'm sorry...\n");
         else printf("%d\n",ans);
     }
     ;
 }

Problem:ZOJ P3164

P3195:LCA

预处理每个点到根节点的距离dist

记三个点为v1,v2,v3,两两配对的LCA分别为u1,u2,u3,那么ans=dist(v1)+dist(v2)+dist(v3)-dist(u1)-dist(u2)-dist(u3)

毫不夸张的说这是我写过的最恶心的代码( ̄﹏ ̄)

map和多余的qv*数组都可以省下

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <utility>
  5 #include <map>
  6
  7 typedef std::pair<int,int> Pr;
  8
  9 std::map <Pr,int> lca;
 10
 11 const int maxQ=420005;
 12 const int maxN=50005;
 13 const int __maxN=70005;
 14
 15 Pr query[maxQ]; // first=to // second=next
 16 int qHead[maxN];
 17 int qCnt;
 18
 19 struct Edge
 20 {
 21     int to;
 22     int weight;
 23     int next;
 24
 25     void assign(int t,int w,int n)
 26     {
 27         to=t; weight=w; next=n;
 28     }
 29 };
 30
 31 Edge edge[maxN*2];
 32 int eHead[maxN];
 33 int eCnt;
 34
 35 void initL()
 36 {
 37     lca.clear();
 38     qCnt = eCnt = 0;
 39     memset(eHead,-1,sizeof(eHead));
 40     memset(qHead,-1,sizeof(qHead));
 41 }
 42
 43 inline void addEdge(int v1,int v2,int w)
 44 {
 45     edge[eCnt].assign(v2,w,eHead[v1]);
 46     eHead[v1]=eCnt++;
 47     edge[eCnt].assign(v1,w,eHead[v2]);
 48     eHead[v2]=eCnt++;
 49 }
 50
 51 inline void addQuery(int v1,int v2)
 52 {
 53     query[qCnt].first=v2;
 54     query[qCnt].second=qHead[v1];
 55     qHead[v1]=qCnt++;
 56     query[qCnt].first=v1;
 57     query[qCnt].second=qHead[v2];
 58     qHead[v2]=qCnt++;
 59 }
 60
 61 int N,Q;
 62 int qv1[__maxN],qv2[__maxN],qv3[__maxN];
 63
 64 bool input()
 65 {
 66     if(scanf("%d",&N)==EOF) return false;
 67     initL();
 68     int v1,v2,w;
 69     for(int i=1;i<N;i++)
 70     {
 71         scanf("%d%d%d",&v1,&v2,&w);
 72         addEdge(v1,v2,w);
 73     }
 74     scanf("%d",&Q);
 75     for(int i=1;i<=Q;i++)
 76     {
 77         scanf("%d%d%d",qv1+i,qv2+i,qv3+i);
 78         addQuery(qv1[i],qv2[i]);
 79         addQuery(qv2[i],qv3[i]);
 80         addQuery(qv1[i],qv3[i]);
 81     }
 82     return true;
 83 }
 84
 85 bool vis[maxN];
 86 int dist[maxN];
 87
 88 void initV()
 89 {
 90     memset(vis,0,sizeof(vis));
 91 }
 92
 93 void build(int cur,int len)
 94 {
 95     vis[cur]=true;
 96     dist[cur]=len;
 97     for(int e=eHead[cur];e>-1;e=edge[e].next)
 98         if(!vis[edge[e].to])
 99             build(edge[e].to,len+edge[e].weight);
100 }
101
102 int setn[maxN];
103
104 void initS()
105 {
106     for(int i=1;i<=N;i++) setn[i]=i;
107     memset(vis,0,sizeof(vis));
108 }
109
110 int find(int x) { return setn[x]==x?x:setn[x]=find(setn[x]); }
111
112 void dfs(int cur)
113 {
114     vis[cur]=true;
115     for(int e=eHead[cur];e>-1;e=edge[e].next)
116         if(!vis[edge[e].to])
117     {
118         dfs(edge[e].to);
119         setn[edge[e].to]=cur;
120     }
121     for(int q=qHead[cur];q>-1;q=query[q].second)
122         if(vis[query[q].first])
123         {
124             int anc=setn[find(query[q].first)];
125             lca[Pr(cur,query[q].first)]=anc;
126             lca[Pr(query[q].first,cur)]=anc;
127         }
128 }
129
130 void solve_aux()
131 {
132     for(int i=1;i<=Q;i++)
133     {
134         int lca1=lca[Pr(qv1[i],qv2[i])];
135         int lca2=lca[Pr(qv2[i],qv3[i])];
136         int lca3=lca[Pr(qv1[i],qv3[i])];
137         printf("%d\n",dist[qv1[i]]+dist[qv2[i]]+dist[qv3[i]]-
138                 dist[lca1]-dist[lca2]-dist[lca3]);
139     }
140 }
141
142 int flag=0;
143 void solve()
144 {
145     if(flag++) printf("\n");
146     initV();
147     build(0,0);
148     initS();
149     dfs(0);
150     solve_aux();
151 }
152
153 int main()
154 {
155     while(input()) solve();
156     return 0;
157 }

A Very Nasty Solution to ZOJ P3195

P3197:区间覆盖问题,贪心思想很简单,但是代码并不好写(´・ω・`)

最后参(chao)考(xi)了这位的代码才AC掉:http://blog.csdn.net/zhangwenjun32/article/details/4149683

此题很重要

 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 #include <utility>

 typedef std::pair<int,int> Pr;
 ;

 Pr rg[maxN];
 int N;

 void input()
 {
     scanf("%d",&N);
     ;i<=N;i++)
         scanf("%d%d",&rg[i].first,&rg[i].second);
 }

 int solve()
 {
     std::sort(rg+,rg+N+);
     ),end();
     );
     );
     while(end<N)
     {
         int tp=-maxN;
         begin=end+;
         for(;cur<=N && rg[cur].first<=begin;cur++)
             tp=std::max(tp,rg[cur].second);
         ++ans; end=tp;
     }
     return ans;
 }

 int main()
 {
     int T; scanf("%d",&T);
     while(T--)
     {
         input();
         printf("%d\n",solve());
     }
     ;
 }

Problem:ZOJ P3197

P3201:树形DP

因为很久没写树形DP了所以卡了很久……

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 int N,M;
 ;

 int lch[maxN];
 int rch[maxN];
 int adjList[maxN][maxN];
 int head[maxN];
 bool vis[maxN];

 int dpQueue[maxN];
 int dp[maxN][maxN];
 int dpa[maxN][maxN];
 int qp;

 int val[maxN];

 void init()
 {
     memset(lch,-,sizeof(lch));
     memset(rch,-,sizeof(rch));
     memset(head,,sizeof(head));
     memset(vis,,sizeof(vis));
     ;i<maxN;i++) dp[i][]=dpa[i][]=;
     qp=;
 }

 bool input()
 {
     if(scanf("%d%d",&N,&M)==EOF) return false;

     init();
     ;i<=N;i++) scanf("%d",val+i);

     int v1,v2;
     ;i<N;i++)
     {
         scanf("%d%d",&v1,&v2);
         ++v1; ++v2;
         adjList[v1][head[v1]++]=v2;
         adjList[v2][head[v2]++]=v1;
     }

     return true;
 }

 void build(int cur)
 {
     vis[cur]=true;
     int next,i;
     int last;
     ;i<head[cur];i++)
     {
         next=adjList[cur][i];
         if(!vis[next])
         {
             last=lch[cur]=next;
             build(next);
             break;
         }
     }
     if(i==head[cur]) return;

     for(;i<head[cur];i++)
     {
         next=adjList[cur][i];
         if(!vis[next])
         {
             build(next);
             last=rch[last]=next;
         }
     }
 }

 void dfs(int cur)
 {
     ) dfs(rch[cur]);
     ) dfs(lch[cur]);
     dpQueue[qp++]=cur;
 }

 const int minf=0xf0000000;

 int solve_aux()
 {
     int ans=minf;
     ;i<qp;i++)
     {
         ;
         int cur=dpQueue[i];
         ) status|=;
         ) status|=;

         int lc,rc;
         switch(status)
         {
         :
             dp[cur][]=dpa[cur][]=val[cur];
             ;j<=M;j++) dp[cur][j]=dpa[cur][j]=minf;
             break;
         :
             rc=rch[cur];
             dp[cur][]=val[cur];
             ;j<=M;j++) dp[cur][j]=minf;
             ;j<=M;j++)
                 dpa[cur][j]=std::max(dpa[rc][j],dpa[rc][j-]+val[cur]);
             break;
         :
             lc=lch[cur];
             ;j<=M;j++)
                 dp[cur][j]=dpa[cur][j]=dpa[lc][j-]+val[cur];
             break;
         :
             lc=lch[cur]; rc=rch[cur];
             ;j<=M;j++)
                 dp[cur][j]=dpa[lc][j-]+val[cur];
             ;j<=M;j++)
             {
                 dpa[cur][j]=minf;
                 ;k<=j;k++)
                     dpa[cur][j]=std::max(dpa[cur][j],dpa[rc][j-k]+dp[cur][k]);
             }
             break;
         }
         ans=std::max(ans,dp[cur][M]);
     }
     return ans;
 }

 int solve()
 {
     build();
     dfs();
     return solve_aux();
 }

 int main()
 {
     while(input()) printf("%d\n",solve());
     ;
 }

Problem:ZOJ P3201

P3224:分段讨论

 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 #include <iostream>

 typedef long long Lint;
 ;
 ;

 using std::cin;
 using std::cout;

 Lint ex[maxN][maxL];
 int N;
 Lint A,B;
 Lint v[maxN];
 Lint r[maxN*maxL];
 int cnt;

 bool input()
 {
     if(!(cin>>N)) return false;
     cin>>A>>B;
     ;i<N;i++) cin>>v[i];
     return true;
 }

 void initExp()
 {
     cnt=;
     ;i<N;i++)
     {
         ex[i][]=1LL;
         ;;j++)
         {
             ex[i][j]=ex[i][j-]*v[i];
             if(ex[i][j]<=B) r[cnt++]=ex[i][j];
             else break;
         }
     }
     r[cnt++]=B+;
     std::sort(r,r+cnt);
     cnt=std::unique(r,r+cnt)-r;
 }

 Lint gcd(Lint a,Lint b)
 {
     return b ? gcd(b,a%b) : a;
 }

 Lint solve_aux(Lint X)
 {
     Lint ans(0LL);
     ;i<cnt-;i++)
     {
         bool ok=true;
         ;j<N;j++) if(r[i]<v[j])
             { ok=false; break; }
         if(!ok) continue;
         Lint lcm=1LL;
         ;j<N;j++)
         {
             Lint k=0LL;
             while(r[i]>=ex[j][k]) k++;
             k--;
             lcm=lcm*k/gcd(lcm,k);
         }
         Lint L=r[i],R=r[i+]-;
         if(L>X) break;
         if(R>=X)
         {
             R=X; ok=false;
         }
         if(L%lcm) L+=(lcm-L%lcm);
         if(R%lcm) R-=R%lcm;
         ans+=(R-L)/lcm+1LL;
         if(!ok) break;
     }
     return ans;
 }

 Lint solve()
 {
     initExp();
     return solve_aux(B)
             -solve_aux(A-);
 }

 int main()
 {
     while(input())
         cout<<solve()<<"\n";
     ;
 }

Problem:ZOJ P3224

P3231:最小费用流

易证:如果若干个整数的和为定值,那么它们的方差最小时,任意两个数的差不会超过1

于是此题可以转换成有上下界的最小费用流问题

建图方法:对于有流量下界的弧,建两条边:一条流量为其下界,费用为cost-inf;一条流量为上、下界之差,费用为cost(cost为该弧的费用)

对于本题,建立源点与每个节点连边(费用为0,流量为该节点原有的苹果数),树上的边视为双向边建立两条弧(流量为inf,费用为搬运一个苹果的成本),再将每个节点与汇点连边(若苹果总数tot能被N整除,每条边的流量为tot/N,费用为0;否则,按有流量下界的方法建两条边,流量分别为tot/N和1,费用分别为-inf和0)

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 struct Edge
 {
     int to;
     int next;
     int capacity;
     int cost;

     void assign(int t,int n,int ca,int co)
     {
         to=t; next=n;
         capacity=ca;
         cost=co;
     }
 };

 ;
 ;
 ;
 ;
 ;

 Edge edgeList[maxE];
 int head[maxN];
 ;

 void init()
 {
     memset(head,-,sizeof(head));
     edgeCnt=;
 }

 inline void addEdge(int from,int to,int ca,int co)
 {
     edgeList[edgeCnt].assign(to,head[from],ca,co);
     head[from]=edgeCnt++;
     edgeList[edgeCnt].assign(,-co);
     head[to]=edgeCnt++;
 }

 int N;
 int ave;
 int apple[maxN];
 bool exactDiv;

 bool input()
 {
     if(scanf("%d",&N)==EOF) return false;

     init();
     ;i<=N;i++) scanf("%d",apple+i);
     ; exactDiv=false;
     ;i<=N;i++) tot+=apple[i];
     ) exactDiv=true;

     ;i<=N;i++) addEdge(src,i,apple[i],);

     int v1,v2,l;
     ;i<N;i++)
     {
         scanf("%d%d%d",&v1,&v2,&l);
         ++v1; ++v2;
         addEdge(v1,v2,inf,l);
         addEdge(v2,v1,inf,l);
     }

     ave=tot/N;
     ;i<=N;i++)
         addEdge(i,sink,ave,);
     ;i<=N;i++)
     {
         addEdge(i,sink,ave,-inf);
         addEdge(i,sink,,);
     }

     return true;
 }

 #include <queue>

 const int distInf=0x3f3f3f3f;

 std::queue<int> bfsq;
 int dist[maxN];
 int prev[maxN];
 int prevEdge[maxN];
 bool inq[maxN];

 bool spfa()
 {
     memset(dist,0x3f,sizeof(dist));
     memset(inq,,sizeof(inq));
     dist[src]=;
     bfsq.push(src);

     while(!bfsq.empty())
     {
         int cur=bfsq.front();
         bfsq.pop();
         inq[cur]=false;

         int t;
         ;e=edgeList[e].next)
             if(edgeList[e].capacity)
             {
                 t=edgeList[e].to;
                 if(dist[t] > dist[cur] + edgeList[e].cost)
                 {
                     dist[t] = dist[cur] + edgeList[e].cost;
                     prev[t] = cur;
                     prevEdge[t] = e;
                     if(!inq[t])
                     {
                         inq[t]=true;
                         bfsq.push(t);
                     }
                 }
             }
     }

     return dist[sink]<distInf;
 }

 int minCostFlow()
 {
     ;
     while(spfa())
     {
         int flow=inf;
         int e;
         for(int v=sink;v>src;v=prev[v])
         {
             int e=prevEdge[v];
             flow=std::min(flow,edgeList[e].capacity);
         }

         for(int v=sink;v>src;v=prev[v])
         {
             e=prevEdge[v];
             ans+=flow*edgeList[e].cost;
             edgeList[e].capacity-=flow;
             edgeList[e^].capacity+=flow;
         }
     }

     return exactDiv ? ans : ans+N*ave*inf;
 }

 int main()
 {
     while(input()) printf("%d\n",minCostFlow());
     ;
 }

Problem:ZOJ P3231

P3264:背包问题

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 ;

 int totW,N;
 int w1[maxN],w2[maxN],v1[maxN],v2[maxN];
 int rel[maxN];

 bool input()
 {
     if(scanf("%d%d",&totW,&N)==EOF)
         return false;
     totW/=;
     ;i<=N;i++)
     {
         scanf("%d%d%d%d%d",w1+i,v1+i,w2+i,v2+i,rel+i);
         w1[i]/=; w2[i]/=;
     }
     return true;
 }

 int dp[maxW];

 int solve()
 {
     memset(dp,,sizeof(dp));
     ;i<=N;i++)
     {
         int j,mn,mx,mv;
         switch(rel[i])
         {
         :
             for(j=totW;j>=w1[i]+w2[i];j--)
                 dp[j]=std::max(dp[j],dp[j-w1[i]-w2[i]]+v1[i]+v2[i]);
             break;
         :
             if(w1[i]<w2[i])
             {
                 mx=w2[i]; mn=w1[i];
                 mv=;
             }
             else
             {
                 mx=w1[i]; mn=w2[i];
                 mv=;
             }
             for(j=totW;j>=mn;j--)
             {
                 if(j>=mx) dp[j]=std::max(dp[j],
                         std::max(dp[j-w1[i]]+v1[i],dp[j-w2[i]]+v2[i]));
                 else dp[j]=std::max(dp[j],
                         (mv==)?dp[j-w1[i]]+v1[i]:dp[j-w2[i]]+v2[i]);
             }
             break;
         :
             for(j=totW;j>=w1[i]+w2[i];j--)
                 dp[j]=std::max(dp[j],
                         std::max(dp[j-w1[i]]+v1[i],dp[j-w1[i]-w2[i]]+v1[i]+v2[i]));
             for(;j>=w1[i];j--)
                 dp[j]=std::max(dp[j],dp[j-w1[i]]+v1[i]);
             break;
         }
     }
     return dp[totW];
 }

 int main()
 {
     while(input()) printf("%d\n",solve());
     ;
 }

Problem:ZOJ P3264

P3279:树状数组+二分

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 int bit[maxN];
 int pref[maxN];
 int cnt[maxN];
 int N,Q;

 inline int lb(int x)
 {
     return x & -x;
 }

 bool input()
 {
     if(scanf("%d",&N)==EOF) return false;
     ]=;
     ;i<=N;i++)
     {
         scanf("%d",&v);
         cnt[i]=v;
         pref[i]=pref[i-]+v;
     }
     ;i<=N;i++)
         bit[i]=pref[i]-pref[i-lb(i)];
     return true;
 }

 void solve()
 {
     scanf("%d",&Q);
     char cmd;
     int ans;
     int left,right,mid;
     int a,b;
     while(Q--)
     {
         do cmd=getchar(); while(cmd==' ' || cmd=='\n');
         if(cmd=='q')
         {
             scanf("%d",&a);
             left=; right=N;
             while(left<right)
             {
                 mid=(left+right)>>;
                 ans=;
                 for(int i=mid;i;i-=lb(i)) ans+=bit[i];
                 ;
                 else right=mid;
             }
             printf("%d\n",left);
         }
         else
         {
             scanf("%d%d",&a,&b);
             for(int i=a;i<=N;i+=lb(i))
                 bit[i]+=(b-cnt[a]);
             cnt[a]=b;
         }
     }
 }

 int main()
 {
     while(input()) solve();
     ;
 }

Problem:ZOJ P3279

P3280:和2688一个套路

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 ];
 int val[maxN];
 ];
 int N,M;

 bool input()
 {
     if(scanf("%d%d",&N,&M)==EOF) return false;
     ;i<N;i++)
         ;j<M;j++)
             scanf("%d",dim[i]+j);
     ;i<M;i++)
         scanf("%d",wgt+i);
     return true;
 }

 void setVal(int b)
 {
     ;i<N;i++)
     {
         val[i]=;
         ,k=b;j<M;j++,k>>=)
         {
             ) val[i]+=wgt[j]*dim[i][j];
             else val[i]-=wgt[j]*dim[i][j];
         }
     }
 }

 const int inf=0x70000000;

 int solve()
 {
     int ans=-inf;
     ;b<(<<M);b++)
     {
         setVal(b);
         int mx=-inf,mn=inf;
         ;i<N;i++)
         {
             mx=std::max(mx,val[i]);
             mn=std::min(mn,val[i]);
         }
         ans=std::max(ans,mx-mn);
     }
     return ans;
 }

 int main()
 {
     while(input())
         printf("%d\n",solve());
     ;
 }

Problem:ZOJ P3280

P3281:先用spfa求出每个点到起点的距离,然后进行dfs

此题最恶心的地方在于读数据

 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 #include <map>
 #include <string>
 #include <queue>

 typedef std::string Str;
 ;
 ;
 const char* linkTag="Link:";

 std::map<Str,int> mp;
 char buf[bufLen];
 int dist[maxM];
 int depth[maxM];
 int vis[maxM];
 int N,M;
 int curIdx;

 std::queue<int> que;

 struct Edge
 {
     int to,next;
     void assign(int t,int n) { to=t; next=n; }
 };

 Edge elist[][maxM];
 ][maxM];
 ];

 void addEdge(int type,int from,int to)
 {
     )
     {
         elist[][ecnt[]].assign(to,head[][from]);
         head[][]++;
         elist[][ecnt[]].assign(][to]);
         head[][to]=ecnt[]++;
     }
     )
     {
         elist[][ecnt[]].assign(to,head[][from]);
         head[][]++;
         elist[][ecnt[]].assign(][to]);
         head[][to]=ecnt[]++;
     }
 } //child=0,father=1,linkTo=2,linkFrom=3

 void init()
 {
     memset(head,-,sizeof(head));
     memset(ecnt,,sizeof(ecnt));
     mp.clear();
     curIdx=;
 }

 bool input()
 {
     if(scanf("%d%d",&N,&M)==EOF) return false;
     N*=M;
     scanf("%d",&M);
     fgets(buf,bufLen,stdin); //filter '\n'
     return true;
 }

 int readBuf(int pos,int& st,bool& isLink)
 {
     isLink=true;
     ;i<;i++) if(buf[pos+i]!=linkTag[i]) isLink=false;
     ;
     for(;buf[pos]!=' ' && buf[pos]!='\n' && buf[pos]!='\0';pos++);
     ; ;
     return pos;
 }

 inline int check(const Str& s)
 {
     if(mp.count(s)) return mp[s];
     mp.insert(std::map<Str,int>::value_type(s,++curIdx));
     return curIdx;
 }

 inline int move(int n)
 {
     for(;buf[n]==' ';n++);
     return n;
 }

 void procBuf()
 {
     Str tp;
     ),next();
     );
     int ci,ni;
     bool isLink;
     next=readBuf(pos,st,isLink);
     tp.assign(buf,next);
     ci=check(tp);
     while(st)
     {
         pos=move(next);
         next=readBuf(pos,st,isLink);
         if(isLink)
         {
             tp.assign(buf+pos+,next-pos-);
             ni=check(tp);
             addEdge(,ci,ni);
         }
         else
         {
             tp.assign(buf+pos,next-pos);
             ni=check(tp);
             addEdge(,ci,ni);
         }
     }
 }

 void link()
 {
     ;i<=M;i++)
     {
         fgets(buf,bufLen,stdin);
         procBuf();
     }
 }

 inline void slack(int from,int to,int len)
 {
     dist[to]=dist[from]+len;
     if(!vis[to])
     {
         vis[to]=;
         que.push(to);
     }
 }

 void spfa()
 {
     que.push();
     memset(vis,,sizeof(vis));
     memset(dist,0x3f,sizeof(dist));
     dist[]=;
     while(!que.empty())
     {
         int cur=que.front();
         que.pop();
         vis[cur]=;
         ][cur];e!=-;e=elist[][e].next)
         {
             ][e].to;
             )
                 slack(cur,to,);
         }
         ][cur];e!=-;e=elist[][e].next)
         {
             ][e].to;
             )
                 slack(cur,to,);
         }
         ][cur];e!=-;e=elist[][e].next)
         {
             ][e].to;
             )
                 slack(cur,to,);
         }
     }
 }

 int dfs(int cur,int step)
 {
     int ans=depth[cur];
     ][cur];e!=-;e=elist[][e].next)
     {
         ][e].to;
         <vis[to] && step++dist[to]<=N)
         {
             vis[to]=step+;
             ans=std::max(ans,dfs(to,step+));
         }
     }
     ][cur];e!=-;e=elist[][e].next)
     {
         ][e].to;
         <vis[to] && step++dist[to]<=N)
         {
             vis[to]=step+;
             ans=std::max(ans,dfs(to,step+));
         }
     }
     ][cur];e!=-;e=elist[][e].next)
     {
         ][e].to;
         <vis[to] && step++dist[to]<=N)
         {
             vis[to]=step+;
             ans=std::max(ans,dfs(to,step+));
         }
     }
     return ans;
 }

 void calcDepth()
 {
     depth[]=;
     que.push();
     while(!que.empty())
     {
         int cur=que.front();
         que.pop();
         ][cur];e!=-;e=elist[][e].next)
         {
             ][e].to;
             depth[to]=depth[cur]+;
             que.push(to);
         }
     }
 }

 int solve()
 {
     memset(vis,0x3f,sizeof(vis));
     vis[]=;
     calcDepth();
     ,);
 }

 int main()
 {
     while(input())
     {
         init();
         link();
         spfa();
         printf("%d\n",solve());
     }
     ;
 }

Problem:ZOJ P3281

P3283:有三个要点:

(1)B很大而C很小,所以求a[i]的B次幂无需快速幂算法,直接求循环节即可

(2)通过dp将求和转化为求方案数

  dp[x][n]表示对于前x个数,取若干个,其B次幂的乘积取余等于n的方案总数,初始时dp[0][1]=1

  注意题目要求不能包含空集,所以dp[N][1]要减1

(3)高精度取余(其实很简单)

 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 #include <iostream>

 ;
 typedef long long int64;

 int N,C;
 ];
 ];
 ];

 bool input()
 {
     ) return false;
     scanf("%s",B);
     scanf("%d",&C);
     ;i<=N;i++)
         scanf("%d",A+i);
     return true;
 }

 int Bmod(int x)
 {
     ;
     ;B[i]!='\0';i++)
         res=(*res+(B[i]-'))%x;
     return res;
 }

 void getAs()
 {
     ],vis[];
     int len,first;
     cyc[]=;
     ;i<=N;i++)
     {
         memset(vis,-,sizeof(vis));
         vis[]=; len=;
         while(len)
         {
             cyc[len]=cyc[len-]*A[i]%C;
             )
             {
                 first=vis[cyc[len]];
                 break;
             }
             vis[cyc[len]]=len;
             len++;
         }
         As[i]=cyc[first+Bmod(len-first)];
     }
 }

 int64 dp[][];

 int64 solve()
 {
     getAs();
     memset(dp,,sizeof(dp));
     dp[][]=;
     ;i<N;i++)
         ;j<C;j++)
         {
             dp[i+][j]+=dp[i][j];
             dp[i+][j*As[i+]%C]+=dp[i][j];
         }
     --dp[N][];
     int64 res();
     ;i<C;i++)
     {
         res+=i*dp[N][i];
         res%=D;
     }
     return res;
 }

 int main()
 {
     while(input())
         std::cout<<solve()<<"\n";
     ;
 }

Problem:ZOJ P3283

P3284:维护整行(列)的修改量,可以看成是LazyTag思想的一种体现

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;

 int mat[maxN][maxN];
 int deltaR[maxN];
 int deltaC[maxN];
 int R,C,Q;

 bool input()
 {
     if(scanf("%d%d",&R,&C)==EOF) return false;
     ;i<=R;i++)
         ;j<=C;j++)
             scanf("%d",mat[i]+j);
     return true;
 }

 void proc()
 {
     memset(deltaR,,sizeof(deltaR));
     memset(deltaC,,sizeof(deltaC));
     scanf("%d",&Q);
     while(Q--)
     {
         int cmd; scanf("%d",&cmd);
         )
         {
             int r,c;
             scanf("%d%d",&r,&c);
             printf("%d\n",mat[r][c]+deltaR[r]+deltaC[c]);
         }
         else
         {
             int r1,c1,r2,c2,k;
             scanf("%d%d%d%d%d",&r1,&c1,&r2,&c2,&k);
             )
             {
                 if(r1==r2) for(int i=c1;i<=c2;i++) mat[r1][i]+=k;
                 else
                 {
                     for(int i=c1;i<=C;i++) mat[r1][i]+=k;
                     ;i<r2;i++) deltaR[i]+=k;
                     ;i<=c2;i++) mat[r2][i]+=k;
                 }
             }
             else
             {
                 if(c1==c2) for(int i=r1;i<=r2;i++) mat[i][c1]+=k;
                 else
                 {
                     for(int i=r1;i<=R;i++) mat[i][c1]+=k;
                     ;i<c2;i++) deltaC[i]+=k;
                     ;i<=r2;i++) mat[i][c2]+=k;
                 }
             }
         }
     }
 }

 );
 int main()
 {
     while(input())
     {
         printf("Case %d\n",++cs);
         proc();
     }
     ;
 }

Problem:ZOJ P3284

P3297:顺序扫描(此题数据特别坑,必须检查合法性)

 #include <cstdio>
 #include <cstring>
 #include <algorithm>

 ;
 ;

 int N,K;
 int C[maxN],A[maxK],B[maxK];

 bool input()
 {
     if(scanf("%d%d",&N,&K)==EOF) return false;
     ;i<=N;i++) scanf("%d",C+i);
     ;i<=K;i++) scanf("%d%d",A+i,B+i);
     return true;
 }

 ;

 int okCnt;
 int cnt[maxK];
 int head,tail;
 int exc;

 void init()
 {
     okCnt=; head=tail=; exc=;
     memset(cnt,,sizeof(cnt));
     ;i<=K;i++)
          && B[i]>=) ++okCnt;
 }

 bool check()
 {
     ;i<=K;i++)
     {
         if(A[i]>B[i]) return false;
         ) return false;
     }
     return true;
 }

 int moveHead()
 {
     ++head; int& cur=C[head];
     ;
     ++cnt[cur];
     if(cnt[cur]==A[cur])
         ;
     )
     {
         --okCnt;
         exc=cur;
         ;
     }
     ;
 }

 int moveTail()
 {
     ++tail; int& cur=C[tail];
     --cnt[cur];
     if(cnt[cur]==B[cur])
     {
         ++okCnt;
         ; ; }
     }
     )
     {
         --okCnt;
         ) ;
     }
     ;
 }

 int solve()
 {
     init();
     ;
     int ans=inf;
     ;
     while(st)
     {
         if(okCnt==K) ans=std::min(ans,head-tail);
         ) st=moveHead();
         else st=moveTail();
     }
     :ans;
 }

 int main()
 {
     while(input()) printf("%d\n",solve());
     ;
 }

Problem:ZOJ P3297

————To be continued————

05-08 15:29