POJ刷题记录 (。・`ω´・)(Progress:6/50)
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)的更多相关文章
- ZOJ 刷题记录 (。・ω・)ノ゙(Progress:31/50)
[热烈庆祝ZOJ回归] P1002:简单的DFS #include <cstdio> #include <cstring> #include <algorithm> ...
- $2019$ 暑期刷题记录1:(算法竞赛DP练习)
$ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...
- PE刷题记录
PE刷题记录 PE60 / 20%dif 这道题比较坑爹. 所有可以相连的素数可以构成一张图,建出这张图,在其中找它的大小为5的团.注意上界的估算,大概在1W以内.1W内有1229个素数,处理出这些素 ...
- leetcode刷题记录--js
leetcode刷题记录 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但 ...
- Leetcode刷题记录(python3)
Leetcode刷题记录(python3) 顺序刷题 1~5 ---1.两数之和 ---2.两数相加 ---3. 无重复字符的最长子串 ---4.寻找两个有序数组的中位数 ---5.最长回文子串 6- ...
- 刷题记录:[HarekazeCTF2019]encode_and_encode
目录 刷题记录:[HarekazeCTF2019]encode_and_encode 一.知识点 JSON转义字符绕过 php伪协议 刷题记录:[HarekazeCTF2019]encode_and_ ...
- 刷题记录:[De1CTF 2019]Giftbox && Comment
目录 刷题记录:[De1CTF 2019]Giftbox && Comment 一.知识点 1.sql注入 && totp 2.RCE 3.源码泄露 4.敏感文件读取 ...
- 刷题记录:[强网杯 2019]Upload
目录 刷题记录:[强网杯 2019]Upload 一.知识点 1.源码泄露 2.php反序列化 刷题记录:[强网杯 2019]Upload 题目复现链接:https://buuoj.cn/challe ...
- 刷题记录:[XNUCA2019Qualifier]EasyPHP
目录 刷题记录:[XNUCA2019Qualifier]EasyPHP 解法一 1.error_log结合log_errors自定义错误日志 2.include_path设置包含路径 3.php_va ...
随机推荐
- 数据结构(树状数组):HEOI2012 采花
[题目描述] 萧薰儿是古国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了n朵花,花有c种颜色(用整数1-c表示),且花是排成一排的,以便 ...
- Delphi 用Web App Debugger简单调试ISAPI 转
用Web App Debugger简单调试ISAPI 以isapi为例: 1.新建一个project,用isapi/nsapi: 2.remove这个project中所有的unit: 3.加进你用 ...
- 怎么把GPUImageFIlter处理过的图像保存成UIImage
总共有两种方法能够把GPUImage处理过的图片转化成UIImage 方法一: UIImage *inputImage = [UIImage imageNamed:@"Lambeau ...
- RabbitMQ 概念
RabbitMQ快速概念入门 转(http://blog.csdn.net/qq_16414307/article/details/50585630) 本文适有一定消息队列基础的,但没有接触过Ra ...
- 【Android - 进阶】之图片三级缓存的原理及实现
在Android开发中,如果图片过多,而我们又没有对图片进行有效的缓存,就很容易导致OOM(Out Of Memory)错误.因此,图片的缓存是非常重要的,尤其是对图片非常多的应用.现在很多框架都做了 ...
- Android 动画之RotateAnimation应用详解
android中提供了4中动画: AlphaAnimation 透明度动画效果 ScaleAnimation 缩放动画效果 TranslateAnimation 位移动画效果 RotateAnimat ...
- hibernate官方新手教程 (转载)
hibernate官方新手教程第一部分 - 第一个Hibernate程序 首先我们将创建一个简单的控制台(console-based)Hibernate程序.我们使用内置数据库(in-memory d ...
- docker 查看容器详细
http://www.docker.org.cn/book/docker/checking-running-image-12.html
- 内核与内核模块:depmod,lsmod,modinfo,insmod,rmmod,mdprobe
内核模块:/lib/modules/version/kernel或/lib/modules/$(uname -r)/kernel; [root@localhost kern ...
- QT程序打包发布(双击运行)