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

2014 ACM/ICPC Asia Regional Shanghai Online

时间:2014-09-27 20:59:30      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   sp   

Tree http://acm.hdu.edu.cn/showproblem.php?pid=5044

树链剖分,区间更新的时候要用on的左++右--的标记方法,要手动扩展,用c++交,综合以上的条件可过。

bubuko.com,布布扣
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #pragma comment(linker, "/STACK:36777216")
  5 #define mt(a,b) memset(a,b,sizeof(a))
  6 using namespace std;
  7 typedef __int64 LL;
  8 const int M=100010;
  9 struct G{
 10     struct E{
 11         int v,next;
 12     }e[M<<1];
 13     int le,head[M];
 14     void init(){
 15         le=0;
 16         mt(head,-1);
 17     }
 18     void add(int u,int v){
 19         e[le].v=v;
 20         e[le].next=head[u];
 21         head[u]=le++;
 22     }
 23 }g;
 24 int n,val[M],fa[M],dep[M],num[M],son[M],top[M],sid[M];
 25 void dfs(int u){
 26     num[u]=1;
 27     son[u]=0;
 28     for(int i=g.head[u];~i;i=g.e[i].next){
 29         int v=g.e[i].v;
 30         if(v!=fa[u]){
 31             fa[v]=u;
 32             dep[v]=dep[u]+1;
 33             dfs(v);
 34             if(num[son[u]]<num[v]) son[u]=v;
 35             num[u]+=num[v];
 36         }
 37     }
 38 }
 39 void get(int u,int Top){
 40     sid[u]=++n;
 41     top[u]=Top;
 42     if(son[u]) get(son[u],top[u]);
 43     for(int i=g.head[u];~i;i=g.e[i].next){
 44         int v=g.e[i].v;
 45         if(v!=fa[u]&&v!=son[u]){
 46             get(v,v);
 47         }
 48     }
 49 }
 50 LL lazy[M],ans[M];
 51 void query(){
 52     LL now=0;
 53     for(int i=1;i<=n;i++){
 54         now+=lazy[i];
 55         ans[i]=now;
 56     }
 57 }
 58 void update(int x,int y,int z){
 59     lazy[x]+=z;
 60     lazy[y+1]-=z;
 61 }
 62 void worknode(int x,int y,int z){
 63     int tx=top[x],ty=top[y];
 64     while(tx!=ty){
 65         if(dep[tx]<dep[ty]){
 66             swap(tx,ty);
 67             swap(x,y);
 68         }
 69         update(sid[tx],sid[x],z);
 70         x=fa[tx];
 71         tx=top[x];
 72     }
 73     if(dep[x]>dep[y]) swap(x,y);
 74     update(sid[x],sid[y],z);
 75 }
 76 void workedge(int x,int y,int z){
 77     int tx=top[x],ty=top[y];
 78     while(tx!=ty){
 79         if(dep[tx]<dep[ty]){
 80             swap(tx,ty);
 81             swap(x,y);
 82         }
 83         update(sid[tx],sid[x],z);
 84         x=fa[tx];
 85         tx=top[x];
 86     }
 87     if(x==y) return ;
 88     if(dep[x]>dep[y]) swap(x,y);
 89     update(sid[son[x]],sid[y],z);
 90 }
 91 struct IN{
 92     int type,u,v,w;
 93 }in[M];
 94 struct EDGE{
 95     int u,v;
 96 }edge[M];
 97 int main(){
 98     int t,N,m,u,v;
 99     while(~scanf("%d",&t)){
100         int cas=1;
101         while(t--){
102             scanf("%d%d",&N,&m);
103             g.init();
104             for(int i=0;i<N-1;i++){
105                 scanf("%d%d",&u,&v);
106                 g.add(u,v);
107                 g.add(v,u);
108                 edge[i].u=u;
109                 edge[i].v=v;
110             }
111             n=fa[1]=dep[1]=num[0]=0;
112             dfs(1);
113             get(1,1);
114             char op[8];
115             for(int i=0;i<m;i++){
116                 scanf("%s%d%d%d",op,&in[i].u,&in[i].v,&in[i].w);
117                 if(op[3]==1) in[i].type=1;
118                 else           in[i].type=2;
119             }
120             mt(lazy,0);
121             for(int i=0;i<m;i++){
122                 if(in[i].type&1) worknode(in[i].u,in[i].v,in[i].w);
123             }
124             printf("Case #%d:\n",cas++);
125             query();
126             for(int i=1;i<=N;i++){
127                 if(i>1) printf(" ");
128                 printf("%I64d",ans[sid[i]]);
129             }
130             puts("");
131             mt(lazy,0);
132             for(int i=0;i<m;i++){
133                 if(in[i].type==2) workedge(in[i].u,in[i].v,in[i].w);
134             }
135             query();
136             for(int i=0;i<N-1;i++){
137                 int u=edge[i].u;
138                 int v=edge[i].v;
139                 if(dep[u]<dep[v]){
140                     swap(u,v);
141                 }
142                 if(i) printf(" ");
143                 printf("%I64d",ans[sid[u]]);
144             }
145             puts("");
146         }
147     }
148     return 0;
149 }
View Code

 

 

Contest http://acm.hdu.edu.cn/showproblem.php?pid=5045

根据题目要求,任意时刻都不能出现两个人做题数量的差大于1,也就是差要<=1,也就是m个问题要分成长度为n的等长的几块,每块里面一人做一个。

问题转化为n个人n题目,如何选一种排列来获得最大价值,若暴力枚举,复杂度是10!,所以用状态压缩,降为2^10,从000推到111.

转移时看哪个人没做过题,那么就可以让他做,状态就是他这位变为1,值就是当前状态的值加上这个人做当前的题目可获得的价值,当前的题目正好等于已做过题的人的个数+1.

bubuko.com,布布扣
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define mt(a,b) memset(a,b,sizeof(a))
 5 using namespace std;
 6 double a[16][1024],dp[1<<10];
 7 int one(int x){
 8     int res=0;
 9     while(x){
10         if(x&1) res++;
11         x>>=1;
12     }
13     return res;
14 }
15 int main(){
16     int t,n,m;
17     while(~scanf("%d",&t)){
18         int cas=1;
19         while(t--){
20             scanf("%d%d",&n,&m);
21             for(int i=0;i<n;i++){
22                 for(int j=0;j<m;j++){
23                     scanf("%lf",&a[i][j]);
24                 }
25             }
26             int s=0,num,all=1<<n;
27             bool flag=true;
28             double ans=0;
29             while(flag){
30                 flag=false;
31                 if(s+n<m){
32                     flag=true;
33                     num=n;
34                 }
35                 else{
36                     num=m-s;
37                 }
38                 mt(dp,0);
39                 for(int i=0;i<all;i++){
40                     int yi=one(i);
41                     if(yi>=num) continue;
42                     for(int j=0;j<n;j++){
43                         if((i>>j)&1) continue;
44                         int next=i|(1<<j);
45                         dp[next]=max(dp[next],dp[i]+a[j][s+yi]);
46                     }
47                 }
48                 double big=0;
49                 if(num==n){
50                     big=dp[all-1];
51                 }
52                 else{
53                     for(int i=0;i<all;i++){
54                         if(one(i)==num){
55                             big=max(big,dp[i]);
56                         }
57                     }
58                 }
59                 ans+=big;
60                 s+=n;
61             }
62             printf("Case #%d: %.5f\n",cas++,ans);
63         }
64     }
65     return 0;
66 }
View Code

 

 

 

 

end

2014 ACM/ICPC Asia Regional Shanghai Online

标签:style   blog   http   color   io   os   ar   for   sp   

原文地址:http://www.cnblogs.com/gaolzzxin/p/3997021.html

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