码迷,mamicode.com
首页 > 其他好文 > 详细

poi

时间:2018-02-11 14:38:16      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:钥匙   efi   span   com   open   pre   close   etc   wap   

我太弱了只能做做poi水题。

那就按总AC数倒叙做吧。

诶怎么还是有好多不会的。

 

[POI2007]MEG-Megalopolis

题意:https://www.luogu.org/problemnew/show/P3459

分析:发现查询的起点总是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-Queries

这里:http://www.cnblogs.com/suika/p/8416136.html

 

[POI2008]PLA-Postering

题意:https://www.luogu.org/problemnew/show/P3467

分析:维护一个单调增的栈,如果当前高度大于栈顶,ans+1;否则弹栈直到栈顶小于等于当前高度。

代码:

技术分享图片
 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

 

poi

标签:钥匙   efi   span   com   open   pre   close   etc   wap   

原文地址:https://www.cnblogs.com/suika/p/8441023.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!