POI

[POI2007]MEG-Megalopolishtml

題意:https://www.luogu.org/problemnew/show/P3459ios

分析:發現查詢的起點老是1。把邊下放到點,樹剖裸上。注意1號點是不要的。數組

代碼:數據結構

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 #define N 250050  6 #define lson pos<<1  7 #define rson pos<<1|1  8 int head[N],to[N<<1],nxt[N<<1],cnt,tot;  9 int n,m,dep[N],fa[N],son[N],siz[N],top[N],idx[N];  10 int t[N<<2];  11 char ch[10];  12 void read(int &x)  13 {  14 int f=1;x=0;char s=getchar();  15 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}  16 while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}  17 x*=f;  18 }  19 inline void add(int u,int v)  20 {  21 to[++cnt]=v;  22 nxt[cnt]=head[u];  23 head[u]=cnt;  24 }  25 void dfs1(int x,int y)  26 {  27 dep[x]=dep[y]+1;  28 fa[x]=y;  29 siz[x]=1;  30 for(int i=head[x];i;i=nxt[i])  31  {  32 if(to[i]==y)continue;  33  dfs1(to[i],x);  34 siz[x]+=siz[to[i]];  35 if(siz[to[i]]>siz[son[x]])  36  {  37 son[x]=to[i];  38  }  39  }  40 }  41 void dfs2(int x,int t)  42 {  43 top[x]=t;idx[x]=++tot;  44 if(son[x])dfs2(son[x],t);  45 for(int i=head[x];i;i=nxt[i])  46  {  47 if(to[i]==fa[x]||to[i]==son[x])continue;  48  dfs2(to[i],to[i]);  49  }  50 }  51 void bt(int l,int r,int pos)  52 {  53 if(l==r)  54  {  55 t[pos]=1;return ;  56  }  57 int mid=l+r>>1;  58  bt(l,mid,lson);  59 bt(mid+1,r,rson);  60 t[pos]=t[lson]+t[rson];  61 }  62 void up(int l,int r,int x,int y,int pos)  63 {  64 if(t[pos]==0)return ;  65 if(x<=l&&r<=y)  66  {  67 t[pos]=0;return ;  68  }  69 int mid=l+r>>1;  70 if(x<=mid)up(l,mid,x,y,lson);  71 if(y>mid)up(mid+1,r,x,y,rson);  72 t[pos]=t[lson]+t[rson];  73 }  74 int query(int l,int r,int x,int y,int pos)  75 {  76 if(x<=l&&r<=y)return t[pos];  77 int re=0,mid=l+r>>1;  78 if(x<=mid)re+=query(l,mid,x,y,lson);  79 if(y>mid)re+=query(mid+1,r,x,y,rson);  80 return re;  81 }  82 int main()  83 {  84 scanf("%d",&n);  85 bt(1,n,1);  86 int x,y;  87 for(int i=1;i<n;i++)  88  {  89 scanf("%d%d",&x,&y);  90  add(x,y);  91  add(y,x);  92  }  93 dfs1(1,0);  94 dfs2(1,1);  95 scanf("%d",&m);  96 for(int i=1;i<n+m;i++)  97  {  98 scanf("%s",ch);  99 if(ch[0]=='W') 100  { 101 scanf("%d",&x); 102 y=1; 103 int ans=0; 104 while(top[x]!=top[y]) 105  { 106 if(dep[top[x]]>dep[top[y]])swap(x,y); 107 ans+=query(1,n,idx[top[y]],idx[y],1); 108 y=fa[top[y]]; 109  } 110 if(dep[x]<dep[y])swap(x,y); 111 ans+=query(1,n,idx[y],idx[x],1); 112 printf("%d\n",ans-1); 113  } 114 else 115  { 116 scanf("%d%d",&x,&y); 117 if(x>y)swap(x,y); 118 if(x==1) 119  { 120 up(1,n,idx[y],idx[y],1); 121  } 122 else if(fa[x]==y) 123  { 124 up(1,n,idx[x],idx[x],1); 125  } 126 else 127  { 128 up(1,n,idx[y],idx[y],1); 129  } 130  } 131  } 132 }
View Code

 

[POI2007]ZAP-Queriesless

這裏:http://www.cnblogs.com/suika/p/8416136.htmlide

 

[POI2008]PLA-Postering優化

題意:https://www.luogu.org/problemnew/show/P3467ui

分析:維護一個單調增的棧,若是當前高度大於棧頂,ans+1;不然彈棧直到棧頂小於等於當前高度。spa

代碼:code

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 int st[250050],top,n,ans;  6 int main()  7 {  8 scanf("%d",&n);  9 int x,y; 10 for(int i=1;i<=n;i++) 11  { 12 scanf("%d%d",&y,&x); 13 if(top==0) 14  { 15 ans++; 16 st[top++]=x;continue; 17  } 18 if(x<=st[top-1]) 19  { 20 while(top&&x<st[top-1])top--; 21 if(!top||x>st[top-1])ans++; 22 st[top++]=x; 23  } 24 else 25  { 26 ans++; 27 st[top++]=x; 28  } 29  } 30 printf("%d",ans); 31 }
View Code

 

[POI2005]SKA-Piggy Banks

題意:https://www.luogu.org/problemnew/show/P3420

分析:每一個罐子向裏面含有的鑰匙連邊,顯然圖中不會有複雜的環套環這種,考慮每一個聯通快,若是是環則對答案貢獻爲1,不然對答案貢獻爲入度爲0的點的個數。

代碼:

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 #define N 1000010  6 int n,fa[N],ans,c[N],f[N];  7 void read(int &x)  8 {  9 int f=1;x=0;char s=getchar(); 10 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 11 while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();} 12 x*=f; 13 } 14 int find(int x) 15 { 16 return fa[x]^x?fa[x]=find(fa[x]):x; 17 } 18 int main() 19 { 20  read(n); 21 register int i; 22 int x; 23 for(i=1;i<=n;++i)fa[i]=i; 24 for(i=1;i<=n;++i) 25  { 26  read(x); 27 int di=find(i),dx=find(x); 28 c[i]++; 29 fa[di]=dx; 30  } 31 for(i=1;i<=n;++i) 32  { 33 if(fa[i]==i)ans++; 34  } 35 for(i=1;i<=n;++i) 36  { 37 if(!c[i]) 38  { 39 int di=find(i); 40 if(!f[di])f[di]=1; 41 else ans++; 42  } 43  } 44 printf("%d",ans); 45 }
View Code

 

[POI2008]STA-Station

題意:給出一個N個點的樹,找出一個點來,以這個點爲根的樹時,全部點的深度之和最大

分析:樹形DP,換根時減去兒子的子樹大小加上n-兒子的子樹大小。

代碼:

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 #define N 1000010  6 #define LL long long  7 int head[N],to[N<<1],nxt[N<<1],cnt,n;  8 int dep[N],fa[N],siz[N],ans;  9 LL sum[N],mx; 10 void read(int &x) 11 { 12 int f=1;x=0;char s=getchar(); 13 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 14 while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}x*=f; 15 } 16 inline void add(int u,int v) 17 { 18 to[++cnt]=v; 19 nxt[cnt]=head[u]; 20 head[u]=cnt; 21 } 22 void dfs(int x,int y) 23 { 24 siz[x]=1; 25 dep[x]=dep[y]+1; 26 sum[1]+=dep[x]; 27 fa[x]=y; 28 register int i; 29 for(i=head[x];i;i=nxt[i]) 30  { 31 if(to[i]==y)continue; 32  dfs(to[i],x); 33 siz[x]+=siz[to[i]]; 34  } 35 } 36 void niu(int x) 37 { 38 register int i; 39 for(i=head[x];i;i=nxt[i]) 40  { 41 if(to[i]==fa[x])continue; 42 sum[to[i]]=sum[x]-(siz[to[i]]-1)+(n-siz[to[i]]-1); 43 if(sum[to[i]]>mx) 44  { 45 ans=to[i];mx=sum[to[i]]; 46  } 47 else if(sum[to[i]]==mx&&to[i]<ans)ans=to[i]; 48  niu(to[i]); 49  } 50 } 51 int main() 52 { 53  read(n); 54 int x,y; 55 register int i; 56 for(i=1;i<n;++i) 57  { 58  read(x);read(y); 59  add(x,y);add(y,x); 60  } 61 dfs(1,0); 62 ans=1; 63 mx=sum[1]; 64 niu(1); 65 printf("%d",ans); 66 }
View Code

 

[POI2008]BLO

題意:Byteotia城市有n個 towns m條雙向roads. 每條 road 鏈接 兩個不一樣的 towns ,沒有重複的road. 全部towns連通。

分析:若是這個點不是割點,答案爲2*n-2,不然須要加上以割點子節點爲根的節點個數和剩餘節點互相的乘積之和。

代碼:

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 #define N 100050  6 #define M 1000050  7 #define LL long long  8 int head[N],to[M],nxt[M],siz[N],n,m,cnt;  9 LL ans[N]; 10 int dfn[N],low[N],tot,cur[N]; 11 inline void add(int u,int v){ 12 to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt; 13 to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt; 14 } 15 void read(int &x){ 16 int f=1;x=0;char s=getchar(); 17 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 18 while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}x*=f; 19 } 20 void tarjan(int x){ 21 dfn[x]=low[x]=++tot;siz[x]=1; 22 int sum=0,flg=0; 23 for(int i=head[x];i;i=nxt[i]){ 24 if(!dfn[to[i]]){ 25  tarjan(to[i]); 26 siz[x]+=siz[to[i]]; 27 low[x]=min(low[x],low[to[i]]); 28 if(low[to[i]]>=dfn[x]){ 29 flg++; 30 ans[x]+=1ll*siz[to[i]]*(n-siz[to[i]]); 31 sum+=siz[to[i]]; 32 if(x!=1||flg>1){ 33 cur[x]=1; 34  } 35  } 36  } 37 else low[x]=min(low[x],dfn[to[i]]); 38  } 39 if(cur[x]){ 40 ans[x]+=1ll*(n-sum-1)*(sum+1)+(n-1); 41 }else ans[x]=2*(n-1); 42 } 43 int main(){ 44  read(n),read(m); 45 int x,y; 46 for(int i=1;i<=m;i++){ 47  read(x),read(y); 48  add(x,y); 49  } 50 tarjan(1); 51 for(int i=1;i<=n;i++){ 52 printf("%lld\n",ans[i]); 53  } 54 }
View Code

 

[POI2008]CLO

題意:Byteotia城市有n個 towns m條雙向roads. 每條 road 鏈接 兩個不一樣的 towns ,沒有重複的road. 你要把其中一些road變成單向邊使得:每一個town都有且只有一個入度。

分析:對於每一個連通塊,可以知足條件當且僅當連通塊中邊數大於等於點數,即存在環,用並查集維護一下就行。

代碼:

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 #define N 100020  6 int n,fa[N],v[N],m;  7 int find(int x){  8 if(fa[x]==x)return x;  9 fa[x]=find(fa[x]); 10 v[fa[x]]|=v[x]; 11 return fa[x]; 12 } 13 int main(){ 14 scanf("%d%d",&n,&m); 15 for(int i=1;i<=n;i++)fa[i]=i; 16 int x,y; 17 for(int i=1;i<=m;i++){ 18 scanf("%d%d",&x,&y); 19 int dx=find(x),dy=find(y); 20 if(dx==dy){ 21 v[x]=1;v[y]=1; 22 }else{ 23 fa[dx]=dy; 24  } 25  } 26 for(int i=1;i<=n;i++)find(i); 27 for(int i=1;i<=n;i++)if(fa[i]==i&&v[i]==0){ 28 puts("NIE");return 0; 29 }puts("TAK"); 30 }
View Code

 

[Poi2010]Guilds

題意:給一張無向圖,要求你用黑白給點染色,且知足對於任意一個黑點,至少有一個白點和他相鄰;對於任意一個白點,至少有一個黑點與他相鄰,問可否成功。

分析:判斷一下是否有孤立的點就行。

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 #define N 200020  6 #define M 1200010  7 int head[N],to[M],nxt[M],cnt,n,m,tag[N];  8 inline void add(int u,int v){  9 to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt; 10 } 11 int main(){ 12 scanf("%d%d",&n,&m); 13 int x,y; 14 for(int i=1;i<=m;++i){ 15 scanf("%d%d",&x,&y); 16  add(x,y);add(y,x); 17  } 18 for(int i=1;i<=n;++i){ 19 if(!tag[i])tag[i]=2; 20 int f=0; 21 for(int j=head[i];j;j=nxt[j]){ 22 f=1; 23 if(!tag[to[j]]){ 24 tag[to[j]]=3-tag[i]; 25  } 26  } 27 if(!f){puts("NIE");return 0;} 28  } 29 printf("TAK\n"); 30 }
View Code

 

[POI2009]Tab

題意:2個n*m矩陣,保證同一個矩陣中元素兩兩不一樣。問可否經過若干次交換兩行或交換兩列把第一個矩陣變成第二個。

分析:咱們發現不管是交換行仍是交換列,每行每列出現的數字都是不變的,存一下每一個點對應的行列直接找就行。

注意多是負數。

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 using namespace std;  5 #define N 1000000  6 int P[2000020][2];  7 int a[1010][1010];  8 int n,m,T;  9 int main(){ 10 scanf("%d",&T); 11 int x; 12 while(T--){ 13 scanf("%d%d",&n,&m); 14 for(int i=1;i<=n;i++){ 15 for(int j=1;j<=m;j++){ 16 scanf("%d",&x); 17 P[x+N][0]=i; 18 P[x+N][1]=j; 19  } 20  } 21 int f=0; 22 for(int i=1;i<=n;i++){ 23 for(int j=1;j<=m;j++){ 24 scanf("%d",&a[i][j]); 25 if(P[a[i][j]+N][0]!=P[a[i][1]+N][0]||P[a[i][j]+N][0]==0)f=1; 26 if(P[a[i][j]+N][1]!=P[a[1][j]+N][1]||P[a[i][j]+N][1]==0)f=1; 27  } 28  } 29 puts(f?"NIE":"TAK"); 30 memset(P,0,sizeof(P)); 31  } 32 } 33 
View Code

 

[POI2008]磚塊Klo

題意:N柱磚,但願有連續K柱的高度是同樣的. 你能夠選擇如下兩個動做 1:從某柱磚的頂端拿一塊磚出來,丟掉不要了. 2:從倉庫中拿出一塊磚,放到另外一柱.倉庫無限大. 如今但願用最小次數的動做完成任務.

分析:維護一個支持插入和刪除操做能求中位數的數據結構。平衡樹和對頂堆都可。

代碼:

 1 #include <stdio.h>  2 #include <string.h>  3 #include <algorithm>  4 #include <queue>  5 using namespace std;  6 priority_queue<int, vector<int>,less<int> >p;  7 priority_queue<int, vector<int>,greater<int> >q;  8 #define N 100050  9 #define LL long long 10 int n,k,a[N],L,R,key,lz[N*12],sip,siq; 11 LL sup,suq,ans; 12 void pud(){ 13 if(!p.empty()){ 14 while(lz[p.top()]&&!p.empty()){ 15 lz[p.top()]--;p.pop(); 16  } 17  } 18 if(!q.empty()){ 19 while(lz[q.top()]&&!q.empty()){ 20 lz[q.top()]--;q.pop(); 21  } 22  } 23 } 24 void add(int x){ 25  pud(); 26 while(sip<(k+1)/2&&siq){ 27 int t=q.top();q.pop(); 28  p.push(t); 29 sip++;siq--; 30 suq-=t;sup+=t; 31  pud(); 32  } 33 if(sip==0){ 34 sip++; 35 sup+=x; 36 p.push(x);return ; 37  } 38  pud(); 39 if(x<p.top()){ 40 sip++; 41 sup+=x; 42  p.push(x); 43 }else{ 44 siq++; 45 suq+=x; 46  q.push(x); 47  } 48  pud(); 49 while(sip>(k+1)/2&&sip){ 50 int t=p.top();p.pop(); 51  q.push(t); 52 sip--;siq++; 53 suq+=t;sup-=t; 54  pud(); 55  } 56  pud(); 57 while(sip<(k+1)/2&&siq){ 58 int t=q.top();q.pop(); 59  p.push(t); 60 sip++;siq--; 61 suq-=t;sup+=t; 62  pud(); 63  } 64  pud(); 65 } 66 void del(int x){ 67 lz[x]++; 68 if(x>p.top())siq--,suq-=x; 69 else sip--,sup-=x; 70  pud(); 71 } 72 int main(){ 73 scanf("%d%d",&n,&k); 74 for(int i=1;i<=n;i++){ 75 scanf("%d",&a[i]); 76  } 77 for(int i=1;i<=k;i++){ 78  add(a[i]); 79  } 80 int mid=p.top(); 81 L=1,R=k,ans=1ll*(k+1)/2*mid-sup+suq-1ll*k/2*mid,key=mid; 82 for(int i=k+1;i<=n;i++){ 83  pud(); 84 del(a[i-k]); 85  pud(); 86  add(a[i]); 87 mid=p.top(); 88 if(ans>=1ll*(k+1)/2*mid-sup+suq-1ll*k/2*mid&&1ll*(k+1)/2*mid-sup+suq-1ll*k/2*mid>=0){ 89 ans=1ll*(k+1)/2*mid-sup+suq-1ll*k/2*mid; 90 L=i-k+1;R=i;key=mid; 91  } 92  } 93 printf("%lld\n",ans); 94 for(int i=1;i<=n;i++){ 95 if(i>=L&&i<=R)printf("%d\n",key); 96 else printf("%d\n",a[i]); 97  } 98 }
View Code

 

[Poi2010]Pilots

題意:給一個數列,求一個最長的子段,子段內任意兩元素之差不大於k

分析:單調隊列。用兩個單調隊列存一下最大,最小值。每次求出當前能使得子段合法的最左邊的下標,更新答案。

代碼:

#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define N 3000050 int n,a[N],Q1[N],l1,r1,k,ans; int Q2[N],l2,r2; char nc(){ static char buf[100000], *p1, *p2; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } int rd(){ int x=0;char s=nc(); while(s<'0'||s>'9')s=nc(); while(s>='0'&&s<='9')x=x*10+s-48,s=nc(); return x; } int main(){ k = rd(); n = rd(); int i, now = 1; for(i = 1;i <= n; i++){ a[i] = rd(); while(l1 < r1 && a[i] <= a[Q1[r1 - 1]]) r1--; while(l2 < r2 && a[i] >= a[Q2[r2 - 1]]) r2--; Q1[r1++] = i; Q2[r2++] = i; while(l1 < r1 && l2 < r2 && a[Q2[l2]] - a[Q1[l1]] > k) { if(Q2[l2] > Q1[l1]){ now = Q1[l1] + 1; l1++; }else{ now = Q2[l2] + 1; l2++; } } ans = max(ans, i - now + 1); } printf("%d\n", ans); } 

 [Poi2014]Couriers

http://www.cnblogs.com/suika/p/8594235.html

[POI2007]立方體大做戰tet

題意:給定一個長度爲 $2n$ 的序列,$1$ ~ $n$ 各出現兩次,能夠交換相鄰兩項,兩個一樣的數放在一塊兒會對消,求把全部數對消的最小交換次數。

分析:設兩個數 $AB$ ,考慮它們的可能的排列:$AABB$ . $ABBA$ . 這兩種狀況在最優解中 $AB$ 之間必定不會發生交換。發生交換的只多是 $ABAB$ 這種,而且能夠發現每次操做都會把 $ABAB$ 這種狀況變成不須要交換的另兩種狀況,也就是說,答案 = 全部 $ABAB$ 這種狀況的個數。咱們能夠 $n^2$ 枚舉找一下這種狀況。具體地,咱們掃到一個數,若是這個數之前沒有出現過,則在數的位置上 $+1$ ,不然,在這個數第一次出現的位置到當前位置開始,求這段區間和並加到 $ans$ 中,而後在第一次出現的位置上 $-1$ 。

用樹狀數組優化一下便可。

代碼:

#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 1000500 #define LL long long LL ans,c[N],a[N],n,pos[N]; void fix(int x,int v) { for(;x<=n+n;x+=x&(-x)) c[x]+=v; } LL inq(int x) { LL re=0; for(;x;x-=x&(-x)) re+=c[x]; return re; } int main() { //freopen("Rumia.in","r",stdin); //freopen("Rumia.out","w",stdout); scanf("%lld",&n); int i,x; for(i=1;i<=n+n;i++) { scanf("%d",&x); if(pos[x]==0) { pos[x]=i; fix(i,1); } else{ ans+=inq(i-1)-inq(pos[x]);fix(pos[x],-1); } } printf("%lld\n",ans); } /* 5 5 2 3 1 4 1 4 3 5 2 */ 

 [POI2004]PRZ:

http://www.cnblogs.com/suika/p/8551872.html

[Poi2011]Strongbox:

題意:有一個密碼箱,0到n-1中的某些整數是它的密碼。
且知足,若是a和b都是它的密碼,那麼(a+b)%n也是它的密碼(a,b能夠相等)
某人試了k次密碼,前k-1次都失敗了,最後一次成功了。
問:該密碼箱最多有多少不一樣的密碼。

分析:能夠證實密碼必定是必定有一個最小的間隔,且這個最小間隔必定是$gcd(n,k)$的約數。而後枚舉約數判斷是否能夠。

但仍是容易T,發現gcd(n,a[i])有不少相同的值,因而去重後A了。

代碼:

#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> using namespace std; typedef long long ll; ll gcd(ll x,ll y) { return y?gcd(y,x%y):x; } ll n,k,a[250050]; char nc() { static char buf[100000],*p1,*p2; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline ll rd() { register ll x=0; register char s=nc(); while(s<'0'||s>'9')s=nc(); while(s>='0'&&s<='9')x=x*10+s-'0',s=nc(); return x; } inline bool check(ll x) { register int i; for(i=1;i<=k;i++) if(a[i]%x==0) return 0; return 1; } int main() { n=rd(); k=rd(); register int i; for(i=1;i<=k;i++) { a[i]=rd(); a[i]=gcd(a[i],n); } ll base=a[k]; sort(a+1,a+k); k=unique(a+1,a+k)-a-1; int b=ceil(sqrt(base)); ll ans=0; for(i=1;i<=b;i++) { if(base%i==0) { if(check(i)) {printf("%lld\n",n/i);return 0;} else if(check(base/i)) ans=n/(base/i); } } printf("%lld\n",ans); } 

 [Poi2012]Letters:

直接求逆序對便可。

代碼:

#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 1000050 #define LL long long char s1[N],s2[N]; int a[N],b[N],n,pos[30],ch[30][100050]; LL c[N],ans; LL inq(int x) { LL re=0; for(;x;x-=x&(-x)) re+=c[x]; return re; } void fix(int x,LL v) { for(;x<=n;x+=x&(-x)) c[x]+=v; } int main() { scanf("%d%s%s",&n,s1+1,s2+1); int i; for(i=1;i<=n;i++) a[i]=s1[i]-'A'+1, b[i]=s2[i]-'A'+1,ch[a[i]][++ch[a[i]][0]]=i; for(i=1;i<=n;i++) pos[b[i]]++,b[i]=ch[b[i]][pos[b[i]]]; for(i=n;i;i--) ans+=inq(b[i]),fix(b[i],1); printf("%lld\n",ans); } 

 [Poi2012]Well:

http://www.cnblogs.com/suika/p/8888728.html

[Poi1999]洞穴攀行:

裸的最大流

代碼:

#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define inf 100000000 #define N 250 #define M 100050 #define S (1) #define T (n) int n,head[M],to[M],nxt[M],cnt=1,flow[M]; int Q[N],l,r,dep[N]; inline void add(int u,int v,int f) { to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;flow[cnt]=f; } bool bfs() { int i,x; l=r=0; memset(dep,0,sizeof(dep)); dep[S]=1; Q[r++]=S; while(l<r) { x=Q[l++]; for(i=head[x];i;i=nxt[i]) { if(!dep[to[i]]&&flow[i]) { dep[to[i]]=dep[x]+1; if(to[i]==T) return 1; Q[r++]=to[i]; } } } return 0; } int dfs(int x,int mf) { if(x==T)return mf; int nf=0,i; for(i=head[x];i;i=nxt[i])if(dep[to[i]]==dep[x]+1&&flow[i]) { int tmp=dfs(to[i],min(flow[i],mf-nf)); nf+=tmp; flow[i]-=tmp; flow[i^1]+=tmp; if(nf==mf) break; } dep[x]=0; return nf; } void dinic() { int f,ans=0; while(bfs()) while(f=dfs(S,inf)) ans+=f; printf("%d\n",ans); } int main() { scanf("%d",&n); int i,x,y; for(i=1;i<n;i++) { scanf("%d",&x); while(x--) { scanf("%d",&y); if(i==S || y==T) { add(i,y,1); }else add(i,y,inf); add(y,i,0); } } dinic(); } 

 [Poi2000]病毒:

http://www.cnblogs.com/suika/p/8891891.html

Poi2013 Bytecomputer:

http://www.cnblogs.com/suika/p/8678279.html

[POI2015]Kinoman:

http://www.cnblogs.com/suika/p/8893959.html

剩下的以及之後的POI題都單獨更吧,這太長了。

相關文章
相關標籤/搜索