1743:前后作差可以转化成不可重叠最长公共字串问题,运用后缀数组解决(参考罗穗骞神犇的论文)

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

 ;
 ;

 int code[maxL];
 int len;

 int sa[maxL];
 int sr[maxL];
 int ht[maxL];
 int stp[maxL];
 int rdx[maxL];

 bool input()
 {
     scanf("%d",&len);
     if(!len) return false;
     code[]=;
     ;i<=len;i++)
         scanf("%d",code+i);
     ;i<len;i++)
         code[i]=(code[i+]-code[i]+maxV); //range:[1,175]
     len--;
     return true;
 }

 void buildSA()
 {
     ;i<=;i++) rdx[i]=;
     ;i<=len;i++) ++rdx[code[i]];
     ;i<=;i++) rdx[i]+=rdx[i-];
     ;i<=len;i++) sr[i]=rdx[code[i]];

     ;step<len;step<<=)
     {
         memset(rdx,,sizeof(rdx));
         rdx[]=step;
         ;i+step<=len;i++) ++rdx[sr[i+step]];
         ;i<=len;i++) rdx[i]+=rdx[i-];
         for(int i=len;i;i--) {
             ;
             stp[rdx[sk]--]=i;
         }

         memset(rdx,,sizeof(rdx));
         ;i<=len;i++) ++rdx[sr[i]];
         ;i<=len;i++) rdx[i]+=rdx[i-];
         for(int i=len;i;i--) {
             int& cur=stp[i];
             sa[rdx[sr[cur]]--]=cur;
         }

         ]]=;
         bool ok=true;
         ;i<=len;i++)
         {
             int& cur=sa[i];
             ];
             ;
             ;
             if(sr[cur]==sr[prev] && csk==psk)
                 ok=false,srt[cur]=srt[prev];
             else srt[cur]=i;
         }
         memcpy(sr,srt,sizeof(sr));
         if(ok) break;
     }
 }

 void calcHeight()
 {
     ht[]=;
     ;i<=len;i++)
     {
         int& cr=sr[i];
         ) {
             ht[cr]=; continue;
         }
         ht[cr]=ht[sr[i-]]?(ht[sr[i-]]-):;
         ]+ht[cr]];ht[cr]++);
     }
 }

 bool check(int subLen)
 {
     ],mn=sa[];
     ;i<=len;i++)
     {
         if(ht[i]>=subLen)
         {
             mx=std::max(mx,sa[i]);
             mn=std::min(mn,sa[i]);
             if(mx-mn>=subLen) return true;
         }
         else mx=mn=sa[i];
     }
     return false;
 }

 int solve()
 {
     buildSA();
     calcHeight();
     ,right=len;
     while(left<=right)
     {
         ;
         ;
         ;
     }
     )?right+:;
 }

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

Problem:POJ P1743

2516:对于每一种货物分别跑一遍最小费用最大流

输入时需注意,如果一组数据处理到一半就可以判定无解,那么必须将这组数据读完才能处理下一组

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

 ;

 ][];
 ][];
 int N,M,K;
 int sink;

 ][];
 ][];

 bool check(int tp)
 {
     ,totd=;
     ;i<=N;i++) totd+=dem[i][tp];
     ;i<=M;i++) tots+=str[i][tp];
     return tots>=totd;
 }

 void readRem(int ct)
 {
     while(ct--)
     {
         int v;
         ;i<=N;i++)
             ;j<=M;j++)
                 scanf("%d",&v);
     }
 }

 #include <queue>

 ];
 ];
 ];

 bool spfa()
 {
     ;
     std::queue<int> que;
     memset(inq,,sizeof(inq));
     memset(prev,,sizeof(prev));

     ;i<=sink;i++) dist[i]=inf;
     que.push();

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

         ;v<=sink;v++)
             if(cp[cur][v])
         {
             if(dist[v]>dist[cur]+cost[cur][v])
             {
                 dist[v]=dist[cur]+cost[cur][v];
                 prev[v]=cur;
                 if(!inq[v])
                 {
                     inq[v]=true;
                     que.push(v);
                 }
             }
         }
     }
     return dist[sink]<inf;
 }

 int maxFlow()
 {
     ;
     while(spfa())
     {
         int fl=inf;
         for(int v=sink;v;v=prev[v])
         {
             int& p=prev[v];
             fl=std::min(fl,cp[p][v]);
         }
         for(int v=sink;v;v=prev[v])
         {
             int& p=prev[v];
             cp[p][v]-=fl;
             cp[v][p]+=fl;
             res+=fl*cost[p][v];
         }
     }
     return res;
 }

 bool proc()
 {
     scanf("%d%d%d",&N,&M,&K);
     if(!N) return false;

     sink=N+M+;
     ;i<=N;i++)
         ;j<=K;j++)
             scanf("%d",dem[i]+j);

     ;i<=M;i++)
         ;j<=K;j++)
             scanf("%d",str[i]+j);

     ;
     ;tp<=K;tp++)
     {
         if(!check(tp))
         {
             printf("-1\n");
             readRem(K-tp+);
             return true;
         }

         memset(cp,,sizeof(cp));
         memset(cost,,sizeof(cost));

         ;i<=M;i++) cp[][i]=str[i][tp];
         ;i<=N;i++) cp[i+M][sink]=dem[i][tp];
         ;i<=N;i++)
             ;j<=M;j++)
             {
                 scanf("%d",cost[j]+M+i);
                 cost[M+i][j]=-cost[j][M+i];
                 cp[j][M+i]=inf;
             }

         ans+=maxFlow();
     }

     printf("%d\n",ans);
     return true;
 }

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

Problem:POJ P2516

3261:可重叠的k次最长公共字串,思想和P1743类似,二分答案,对height分层(还是参考论文)

如果对数值进行离散化的话可以节省空间,不过我懒得写了(* ̄∇ ̄*)

偶尔用用模板就是爽(*゚▽゚*)

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

 ;
 ;

 int code[maxL];
 int len,K;

 int sa[maxL];
 int sr[maxL];
 int ht[maxL];
 int stp[maxL];
 ];

 void input()
 {
     scanf("%d%d",&len,&K);
     ;i<=len;i++)
         scanf("%d",code+i);
 }

 void buildSA()
 {
     memset(rdx,,sizeof(rdx));
     ;i<=len;i++) ++rdx[code[i]];
     ;i<=apb;i++) rdx[i]+=rdx[i-];
     ;i<=len;i++) sr[i]=rdx[code[i]];

     ;step<len;step<<=)
     {
         memset(rdx,,sizeof(rdx));
         rdx[]=step;
         ;i+step<=len;i++) ++rdx[sr[i+step]];
         ;i<=len;i++) rdx[i]+=rdx[i-];
         for(int i=len;i;i--) {
             ;
             stp[rdx[sk]--]=i;
         }

         memset(rdx,,sizeof(rdx));
         ;i<=len;i++) ++rdx[sr[i]];
         ;i<=len;i++) rdx[i]+=rdx[i-];
         for(int i=len;i;i--) {
             int& cur=stp[i];
             sa[rdx[sr[cur]]--]=cur;
         }

         ]]=;
         bool ok=true;
         ;i<=len;i++)
         {
             int& cur=sa[i];
             ];
             ;
             ;
             if(sr[cur]==sr[prev] && csk==psk)
                 ok=false,srt[cur]=srt[prev];
             else srt[cur]=i;
         }
         memcpy(sr,srt,sizeof(sr));
         if(ok) break;
     }
 }

 void calcHeight()
 {
     ht[]=;
     ;i<=len;i++)
     {
         int& cr=sr[i];
         ) {
             ht[cr]=; continue;
         }
         ht[cr]=ht[sr[i-]]?(ht[sr[i-]]-):;
         ]+ht[cr]];ht[cr]++);
     }
 }

 bool check(int subLen)
 {
     ;
     ;i<=len;i++)
     {
         if(ht[i]>=subLen) {
             if((++cnt)>=K) return true;
         }
         ;
     }
     return false;
 }

 int solve()
 {
     buildSA();
     calcHeight();
     ,right=len;
     while(left<=right)
     {
         ;
         ;
         ;
     }
     return right;
 }

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

Problem:POJ P3261

3368:对单调不递减数列求区间众数,把相同的数合并成一个区间,然后对这些区间进行操作即可

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

 ;
 ;

 int from[maxN];
 int to[maxN];
 int rgCnt;

 int st[logN][maxN];
 int N,Q;

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

     int last=0x90000000;
     int v;
     rgCnt=;
     ;i<=N;i++)
     {
         scanf("%d",&v);
         if(v>last)
         {
             to[rgCnt]=i-;
             from[++rgCnt]=i;
             last=v;
         }
     }
     to[rgCnt]=N;
     return true;
 }

 int log2(int x)
 {
     ;
     while(x)
     {
         ++ans;
         x>>=;
     }
     return ans;
 }

 void initST()
 {
     ;i<=rgCnt;i++)
         st[][i]=to[i]-;
     int ly=log2(rgCnt);

     ;i<=ly;i++)
     {
         <<i)+;
         ;j<=maxj;j++)
             st[i][j]=std::max( st[i-][j],st[i-][j+(<<(i-))] );
     }
 }

 int ask(int L,int R)
 {
     );
     -(<<ly)]);
 }

 int search(int pos)
 {
     ,hi=rgCnt;
     while(lo<hi)
     {
         ;
         ;
         else hi=mid;
     }
     return lo;
 }

 void solve()
 {
     int L,R;
     int ls,rs;
     initST();
     while(Q--)
     {
         scanf("%d%d",&L,&R);
         ls=search(L);
         rs=search(R);
         );
         ==rs)
             printf();
         ,rs-),
                                     std::max(to[ls]-L,R-));
     }
 }

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

Problem:POJ P3368

3378:DP+SBT优化转移(被long long溢出和高精度卡了很久……>_<)

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

 ;
 typedef long long int64;

 struct Node
 {
     int key;
     int64 sum;
     int64 val;
     ];
     ];

     void assign(int k,int64 v)
     {
         key=k;
         sum=val=v;
         size[]=size[]=;
         ch[]=ch[]=;
     }
 };

 Node sbt[maxN];
 int root,used;

 void initSbt()
 {
     root=used=;
 }

 inline void update(int c)
 {
     sbt[c].sum=sbt[sbt[c].ch[]].sum+sbt[sbt[c].ch[]].sum+sbt[c].val;
 }

 int rotate(int c,int dir) //right-rotate if dir==0
 {
     int next=sbt[c].ch[dir];
     sbt[c].ch[dir]=sbt[next].ch[dir^];
     sbt[c].size[dir]=sbt[next].size[dir^];
     update(c);
     sbt[next].ch[dir^]=c;
     sbt[next].size[dir^]+=sbt[c].size[dir^]+;
     update(next);
     return next;
 }

 int insert_aux(int k,int64 v,int c)
 {
     if(!c)
     {
         sbt[++used].assign(k,v);
         return used;
     }
     int dir = (k >= sbt[c].key); //0 is left; 1 is right
     sbt[c].ch[dir]=insert_aux(k,v,sbt[c].ch[dir]);
     ++sbt[c].size[dir];
     update(c);
     ])
         return rotate(c,dir);
     ] > sbt[c].size[dir^])
     {
         sbt[c].ch[dir]=rotate(sbt[c].ch[dir],dir^);
         return rotate(c,dir);
     }
     else return c;
 }

 inline void insert(int k,int64 v)
 {
     root=insert_aux(k,v,root);
 }

 int64 ask(int mxk)
 {
     int64 ans=;
     int cur=root;
     while(cur)
     {
         if(mxk<=sbt[cur].key)
             cur=sbt[cur].ch[];
         else
         {
             ans+=(sbt[sbt[cur].ch[]].sum+sbt[cur].val);
             cur=sbt[cur].ch[];
         }
     }
     return ans;
 }

 int a[maxN];
 int64 dp[maxN];
 int N;

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

 ;
 ;

 struct BigInt
 {
     int dgt[maxD];
     int len;

     BigInt():len() { memset(dgt,,sizeof(dgt)); }

     BigInt operator += (int64 v)
     {
         ;
         while(v)
         {
             dgt[d]+=(v%rdx);
             for(int f=d;dgt[f]>=rdx;f++)
             {
                 dgt[f]-=rdx;
                 ++dgt[f+];
             }
             ++d; v/=rdx;
         }
         if(len<=d)
             len=d+(dgt[d]?:);
         return *this;
     }

     void print()
     {
         ");
         else
         {
             printf(]);
             ;i>=;i--)
                 printf("%04d",dgt[i]);
         }
         printf("\n");
     }
 };

 void solve()
 {
     ) { printf("0\n"); return; }
     ;i<=N;i++) dp[i]=;
     ;t<=;t++)
     {
         initSbt();
         ;i<t;i++)
         {
             if(dp[i]) insert(a[i],dp[i]);
             dp[i]=;
         }
         for(int i=t;i<=N;i++)
         {
             int64 temp=dp[i];
             dp[i]=ask(a[i]);
             insert(a[i],temp);
         }
     }
     BigInt ans;
     ;i<=N;i++) ans+=dp[i];
     ans.print();
 }

 #include <iostream>

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

Problem:POJ P3378

3728:Tarjan求LCA的变种形式,细节比较多

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

 ;

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

 Edge elist[maxN<<];
 int ehead[maxN];
 int ecnt;

 void addEdge(int v1,int v2)
 {
     elist[ecnt].assign(v2,ehead[v1]);
     ehead[v1]=ecnt++;
     elist[ecnt].assign(v1,ehead[v2]);
     ehead[v2]=ecnt++;
 }

 struct Query
 {
     int from,to,next;
     void assign(int f,int t,int n)
     {
         from=f; to=t; next=n;
     }
 };

 Query qlist[maxN<<];
 int qhead[maxN];
 int qcnt;

 int ans[maxN];

 void addQuery(int v1,int v2)
 {
     qlist[qcnt].assign(v1,v2,qhead[v1]);
     qhead[v1]=qcnt++;
     qlist[qcnt].assign(v2,v1,qhead[v2]);
     qhead[v2]=qcnt++;
 }

 struct Proc
 {
     int idx,next;
     void assign(int i,int n)
     {
         idx=i; next=n;
     }
 };

 Proc plist[maxN];
 int phead[maxN];
 int pcnt;

 void addProc(int v,int idx)
 {
     plist[pcnt].assign(idx,phead[v]);
     phead[v]=pcnt++;
 }

 void initList()
 {
     memset(ehead,-,sizeof(ehead));
     memset(qhead,-,sizeof(qhead));
     memset(phead,-,sizeof(phead));
     ecnt=qcnt=pcnt=;
 }

 int up[maxN],down[maxN],mx[maxN],mn[maxN];
 int wgt[maxN];
 int N,Q;

 void input()
 {
     initList();
     scanf("%d",&N);
     ;i<=N;i++) scanf("%d",wgt+i);
     int v1,v2;
     ;i<N;i++)
     {
         scanf("%d%d",&v1,&v2);
         addEdge(v1,v2);
     }
     scanf("%d",&Q);
     ;i<=Q;i++)
     {
         scanf("%d%d",&v1,&v2);
         addQuery(v1,v2);
     }
 }

 int ftr[maxN];
 bool vis[maxN];

 void initSet()
 {
     memset(vis,,sizeof(vis));
     memset(up,,sizeof(up));
     memset(down,,sizeof(down));
     ;i<=N;i++)
     {
         ftr[i]=i;
         mx[i]=mn[i]=wgt[i];
     }
 }

 int find(int x)
 {
     using std::max;
     using std::min;
     if(ftr[x]==x) return x;
     int temp=ftr[x];
     ftr[x]=find(ftr[x]);
     up[x]=max(mx[temp]-mn[x],max(up[x],up[temp]));
     down[x]=max(mx[x]-mn[temp],max(down[x],down[temp]));
     mx[x]=max(mx[x],mx[temp]);
     mn[x]=min(mn[x],mn[temp]);
     return ftr[x];
 }

 void dfs(int cur)
 {
     vis[cur]=true;
     ;q=qlist[q].next)
     {
         int& to=qlist[q].to;
         if(vis[to])
             addProc(find(to),q);
     }
     ;e=elist[e].next)
     {
         int& to=elist[e].to;
         if(!vis[to])
         {
             dfs(to);
             ftr[to]=cur;
         }
     }
     using std::max;
     ;p=plist[p].next)
     {
         int& idx=plist[p].idx;
         int& from=qlist[idx].from;
         int& to=qlist[idx].to;
         find(from); find(to);
         ) ans[idx>>]=max(mx[from]-mn[to],max(up[to],down[from]));
         ]=max(mx[to]-mn[from],max(up[from],down[to]));
     }
 }

 int main()
 {
     input();
     initSet();
     dfs();
     ;i<Q;i++) printf("%d\n",ans[i]);
     ;
 }

Problem:POJ P3728

POJ刷题记录 (。・`ω´・)(Progress:6/50)的更多相关文章

  1. ZOJ 刷题记录 (。・ω・)ノ゙(Progress:31/50)

    [热烈庆祝ZOJ回归] P1002:简单的DFS #include <cstdio> #include <cstring> #include <algorithm> ...

  2. $2019$ 暑期刷题记录1:(算法竞赛DP练习)

    $ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...

  3. PE刷题记录

    PE刷题记录 PE60 / 20%dif 这道题比较坑爹. 所有可以相连的素数可以构成一张图,建出这张图,在其中找它的大小为5的团.注意上界的估算,大概在1W以内.1W内有1229个素数,处理出这些素 ...

  4. leetcode刷题记录--js

    leetcode刷题记录 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但 ...

  5. Leetcode刷题记录(python3)

    Leetcode刷题记录(python3) 顺序刷题 1~5 ---1.两数之和 ---2.两数相加 ---3. 无重复字符的最长子串 ---4.寻找两个有序数组的中位数 ---5.最长回文子串 6- ...

  6. 刷题记录:[HarekazeCTF2019]encode_and_encode

    目录 刷题记录:[HarekazeCTF2019]encode_and_encode 一.知识点 JSON转义字符绕过 php伪协议 刷题记录:[HarekazeCTF2019]encode_and_ ...

  7. 刷题记录:[De1CTF 2019]Giftbox && Comment

    目录 刷题记录:[De1CTF 2019]Giftbox && Comment 一.知识点 1.sql注入 && totp 2.RCE 3.源码泄露 4.敏感文件读取 ...

  8. 刷题记录:[强网杯 2019]Upload

    目录 刷题记录:[强网杯 2019]Upload 一.知识点 1.源码泄露 2.php反序列化 刷题记录:[强网杯 2019]Upload 题目复现链接:https://buuoj.cn/challe ...

  9. 刷题记录:[XNUCA2019Qualifier]EasyPHP

    目录 刷题记录:[XNUCA2019Qualifier]EasyPHP 解法一 1.error_log结合log_errors自定义错误日志 2.include_path设置包含路径 3.php_va ...

随机推荐

  1. bzoj1260

    很容易脑补出来的区间dp O(n3)的 var f:array[0..51,0..51] of longint;    i,n,j,l,k:longint;    s:string; function ...

  2. Quality in the Test Automation Review Process and Design Review Template

    About this document Prerequisite knowledge/experience: Software Testing, Test Automation Applicable ...

  3. duang体加班版

    领导第一次让我加班的时候,其实我是拒绝的,因为我觉着加班这个事,不能你让我加我就加,晚了就没有地铁了..领导跟我说可以打车报销.加了一个月之后,我的钱包duang~,后来我知道报销其实是假的,我每天打 ...

  4. Openstack部署工具

    Openstack发展很猛,很多朋友都很认同,2013年,会很好的解决OpenStack部署的问题,让安装,配置变得更加简单易用. 很多公司都投入人力去做这个,新浪也计划做一个Openstack的is ...

  5. 机器学习算法库scikit-learn的安装

    scikit-learn 是一个python实现的免费开源的机器学习算法包,从字面意思可知,science 代表科学,kit代表工具箱,直接翻译过来就是用于机器学习的科学计算包. 安装scikit-l ...

  6. centos下apache thrift的安装

    参考:http://running.iteye.com/blog/1983463  thrift-0.9.0安装 最好切换到root用户操作,避免不必要的麻烦. 进行例子程序tutorial目录下,通 ...

  7. hpuoj 问题 A: 做不出来踢协会!!!

    问题 A: 做不出来踢协会!!! 时间限制: 1 Sec  内存限制: 128 MB提交: 291  解决: 33[提交][状态][讨论版] 题目描述 这是今天最水的一道题,如果没写出来的,呵呵,踢协 ...

  8. poj 1064 Cable master【浮点型二分查找】

    Cable master Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29554   Accepted: 6247 Des ...

  9. hdoj 2199 Can you solve this equation?【浮点型数据二分】

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  10. python_将一组数据展示成直方图(以list为例)

    直接上代码: from matplotlib import pyplot as plt # 参数依次为list,抬头,X轴标签,Y轴标签,XY轴的范围 def draw_hist(myList,Tit ...