训练赛二:2013区域赛长春赛区

刚打完三场训练赛,先补完(目前水平)第二场的大部分题,就先写第二场的总结吧

不会找水题,这点区域赛有榜跟还好==

后半场好像梦游了?应该去做进制转换那个的。

还是国内赛好点,刚补了三维线段树和树上倍增,和后面要学习的专题之一概率dp。

这一场还留了两个坑,一个三分和一个高斯消元,下面学习算法的时候回来补

还是好弱,每场只能铜牌区,越打越弱,越弱越打,总会变强的

A签到题

将一个n×m的字符串以n行每行m个输出

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 char s[1005];
 6 int main()
 7 {
 8   int T,n,m,i;
 9   scanf("%d",&T);
10   while (T--)
11   {
12     scanf("%d%d",&n,&m);
13     scanf("%s",s+1);
14     for (i=1;i<=n*m;i++)
15     {
16       printf("%c",s[i]);
17       if (i%m==0) printf("\n");
18     }
19   }
20   return 0;
21 }
View Code

B将n转化为黄金进制

 1 #include<stdio.h>
 2 #include<string.h>
 3 int a[105];
 4 int main()
 5 {
 6   int n,from,to,go,i,tmp;
 7   while (~scanf("%d",&n))
 8   {
 9     memset(a,0,sizeof(a));
10     a[50]=n;
11     while (1)
12     {
13       go=0;
14       for (i=1;i<=100-2;i++)
15         if (a[i]&&a[i+1])
16         {
17           tmp=a[i]<a[i+1]?a[i]:a[i+1];
18           a[i]-=tmp;  a[i+1]-=tmp;
19           a[i+2]+=tmp; go=1;
20         }
21       for (i=3;i<=100-1;i++)
22         if (a[i]>=2)
23         {
24           a[i-2]+=a[i]/2; a[i+1]+=a[i]/2;
25           a[i]-=a[i]/2*2; go=1;
26         }
27       if (!go) break;
28     }
29     from=to=-1;
30     for (i=100;i>=1;i--)
31       if (a[i]==1){
32         to=i;
33         if (from==-1) from=i;
34       }
35     for (i=from;i>=to;i--)
36     {
37       if (i==49) printf(".");
38       printf("%d",a[i]);
39     }
40     printf("\n");
41   }
42 }
View Code

C概率dp

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 double dp[45][45*1005];
 6 int a[45];
 7 int main()
 8 {
 9   int T,n,i,j,sum;
10   double p;
11   scanf("%d",&T);
12   while (T--)
13   {
14     scanf("%d%lf",&n,&p);
15     sum=0;
16     memset(dp,0,sizeof(dp));
17     for (i=1;i<=n;i++)
18     {
19       scanf("%d",&a[i]);
20       sum+=a[i];
21     }
22     dp[0][0]=1.0;
23     for (i=1;i<=n;i++)
24       for (j=0;j<=sum;j++)
25       {
26         dp[i][j]=dp[i-1][j]*0.5;
27         if (j>=a[i]) dp[i][j]+=dp[i-1][j-a[i]]*0.5;
28       }
29     for (i=1;i<=sum;i++) dp[n][i]+=dp[n][i-1];
30     for (i=0;i<=sum;i++)
31       if (dp[n][i]>=p) {
32         printf("%d\n",i);
33         break;
34       }
35   }
36   return 0;
37 }
View Code

D几何不会(三分,留坑)

E神题不会

F高斯消元(留坑)

G二维线段树

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 using namespace std;
  5 int maxv[4*801][4*801],minv[4*801][4*801];
  6 int a[802][802],fmax,fmin,n;
  7 void build_y(int ox,int o,int l,int r,int x,int kind)
  8 {
  9   int mid=l+(r-l)/2;
 10   if (l==r){
 11     if (kind) maxv[ox][o]=minv[ox][o]=a[x][l];
 12     else{
 13       maxv[ox][o]=max(maxv[ox*2][o],maxv[ox*2+1][o]);
 14       minv[ox][o]=min(minv[ox*2][o],minv[ox*2+1][o]);
 15     }
 16     return;
 17   }
 18   build_y(ox,o*2,l,mid,x,kind);
 19   build_y(ox,o*2+1,mid+1,r,x,kind);
 20   maxv[ox][o]=max(maxv[ox][o*2],maxv[ox][o*2+1]);
 21   minv[ox][o]=min(minv[ox][o*2],minv[ox][o*2+1]);
 22 }
 23 void build_x(int o,int l,int r)
 24 {
 25   int mid=l+(r-l)/2;
 26   if (l==r) build_y(o,1,1,n,l,1);
 27   else{
 28     build_x(o*2,l,mid);
 29     build_x(o*2+1,mid+1,r);
 30     build_y(o,1,1,n,0,0);
 31   }
 32 }
 33 void update_y(int ox,int o,int l,int r,int qy,int num,int kind)
 34 {
 35   int mid=l+(r-l)/2;
 36   if (l==r) {
 37     if (kind) maxv[ox][o]=minv[ox][o]=num;
 38     else{
 39       maxv[ox][o]=max(maxv[ox*2][o],maxv[ox*2+1][o]);
 40       minv[ox][o]=min(minv[ox*2][o],minv[ox*2+1][o]);
 41     }
 42     return;
 43   }
 44   if (qy<=mid) update_y(ox,o*2,l,mid,qy,num,kind);
 45   else update_y(ox,o*2+1,mid+1,r,qy,num,kind);
 46   maxv[ox][o]=max(maxv[ox][o*2],maxv[ox][o*2+1]);
 47   minv[ox][o]=min(minv[ox][o*2],minv[ox][o*2+1]);
 48 }
 49 void update_x(int o,int l,int r,int qx,int qy,int num)
 50 {
 51   int mid=l+(r-l)/2;
 52   if (l==r) update_y(o,1,1,n,qy,num,1);
 53   else{
 54     if (qx<=mid) update_x(o*2,l,mid,qx,qy,num);
 55     else update_x(o*2+1,mid+1,r,qx,qy,num);
 56     update_y(o,1,1,n,qy,num,0);
 57   }
 58 }
 59 void query_y(int ox,int o,int l,int r,int y1,int y2)
 60 {
 61   int mid=l+(r-l)/2;
 62   if (y1<=l&&y2>=r){
 63     fmax=max(fmax,maxv[ox][o]);
 64     fmin=min(fmin,minv[ox][o]);
 65     return;
 66   }
 67   if (y1<=mid) query_y(ox,o*2,l,mid,y1,y2);
 68   if (y2>mid) query_y(ox,o*2+1,mid+1,r,y1,y2);
 69 }
 70 void query_x(int o,int l,int r,int x1,int x2,int y1,int y2)
 71 {
 72   int mid=l+(r-l)/2;
 73   if (x1<=l&&x2>=r) query_y(o,1,1,n,y1,y2);
 74   else{
 75     if (x1<=mid) query_x(o*2,l,mid,x1,x2,y1,y2);
 76     if (x2>mid) query_x(o*2+1,mid+1,r,x1,x2,y1,y2);
 77   }
 78 }
 79 int main()
 80 {
 81   int T,t,x,y,l,i,j,m;
 82   scanf("%d",&T);
 83   for (t=1;t<=T;t++)
 84   {
 85     scanf("%d",&n);
 86     for (i=1;i<=n;i++)
 87       for (j=1;j<=n;j++) scanf("%d",&a[i][j]);
 88     build_x(1,1,n);
 89     printf("Case #%d:\n",t);
 90     scanf("%d",&m);
 91     while (m--)
 92     {
 93       scanf("%d%d%d",&x,&y,&l);
 94       l=(l-1)/2; fmax=0; fmin=0x3f3f3f3f;
 95       query_x(1,1,n,max(x-l,1),min(x+l,n),max(y-l,1),min(y+l,n));
 96       printf("%d\n",(fmax+fmin)/2);
 97       update_x(1,1,n,x,y,(fmax+fmin)/2);
 98     }
 99   }
100   return 0;
101 }
View Code

H神题不会

I字符串hash+map判重

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<map>
 4 #include<algorithm>
 5 using namespace std;
 6 #define uLL unsigned long long
 7 const  uLL B=1000000007;
 8 map<uLL,int>mp;
 9 char s[100005];
10 uLL has[100005];
11 int main()
12 {
13   int m,l,len,i,j,flag,ans,now;
14   uLL tmp,w;
15   while (~scanf("%d%d",&m,&l))
16   {
17     scanf("%s",s+1);
18     len=strlen(s+1);
19     //字符串hash
20     tmp=1; w=0;
21     for (i=1;i<l;i++){
22       tmp=tmp*B;
23       w=w*B+s[i]-'a'+1;
24     }
25     w=w*B+s[l]-'a'+1;
26     has[1]=w;
27     for (i=1;i<len-l+1;i++)
28       has[i+1]=(has[i]-tmp*(s[i]-'a'+1))*B+(s[i+l]-'a'+1);
29 //    for (i=1;i<=len-l+1;i++) printf("%llu\n",has[i]);
30 
31     ans=0;
32     for (i=1;i<=l;i++)
33     {
34       mp.clear(); flag=0;
35       for (j=1;j<=m;j++)
36       {
37         now=i+(j-1)*l;
38         if (now>len-l+1) break;
39         mp[has[now]]++;
40         if (mp[has[now]]==2) flag++;
41       }
42       if (now>len-l+1) break; 
43       if (flag==0) ans++;
44       for (j=m+1;;j++)
45       {
46         now=i+(j-1)*l;
47         if (now>len-l+1) break;
48         mp[has[now]]++;
49         if (mp[has[now]]==2) flag++;
50         mp[has[now-l*m]]--;
51         if (mp[has[now-l*m]]==1) flag--;
52         if (flag==0) ans++;
53       }
54     }
55     printf("%d\n",ans);
56   }
57   return 0;
58 }
View Code

J树上倍增

  1 #pragma comment(linker,"/STACK:16777216")
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 using namespace std;
  6 struct dian{
  7   int type,u;
  8 };
  9 int now,next[200005],head[200005],point[200005];
 10 int parent[200005][21],size[200005],depth[200005];
 11 void add(int x,int y)
 12 {
 13   next[++now]=head[x];
 14   head[x]=now;
 15   point[now]=y;
 16 }
 17 void dfs(int u,int pre,int deep)
 18 {
 19   int i,v;
 20   parent[u][0]=pre;
 21   size[u]=1;
 22   depth[u]=deep;
 23   for (i=head[u];i!=-1;i=next[i])
 24   {
 25     v=point[i];
 26     if (v==pre) continue;
 27     dfs(v,u,deep+1);
 28     size[u]+=size[v];
 29   }
 30 }
 31 void rmq_build(int n)
 32 {
 33   for (int k=0;k<20;k++)
 34     for (int u=1;u<=n;u++)
 35       if (parent[u][k]==-1) parent[u][k+1]=-1;
 36       else parent[u][k+1]=parent[parent[u][k]][k];
 37 }
 38 int go_up(int u,int deep)
 39 {
 40   for (int k=0;k<=20;k++)
 41     if ((deep>>k)&1) u=parent[u][k];
 42   return u;
 43 }
 44 int rmq_query(int u,int v)
 45 {
 46   if (depth[u]<depth[v]) swap(u,v);
 47   u=go_up(u,depth[u]-depth[v]);
 48   if (u==v) return u;
 49   for (int k=20;k>=0;k--)
 50     if (parent[u][k]!=parent[v][k])
 51       u=parent[u][k],v=parent[v][k];
 52   return parent[u][0];
 53 }
 54 dian get_middle(int a,int b,int ab)
 55 {
 56   int len=depth[a]+depth[b]-2*depth[ab];
 57   dian n1;
 58   if (depth[a]>=depth[b])
 59     n1.type=1,n1.u=go_up(a,(len-1)/2);
 60   else n1.type=2,n1.u=go_up(b,len/2);
 61   return n1;
 62 }
 63 int n;
 64 int cal(int a,int b,int c,int ab,int ac)
 65 {
 66   dian ab_m=get_middle(a,b,ab),ac_m=get_middle(a,c,ac);
 67   if (ab_m.type==1&&ac_m.type==1)
 68     return depth[ab_m.u]>depth[ac_m.u]?size[ab_m.u]:size[ac_m.u];
 69   else if (ab_m.type==2&&ac_m.type==2){
 70       if (depth[ab_m.u]<depth[ac_m.u]) swap(ab_m,ac_m);
 71       if (rmq_query(ab_m.u,ac_m.u)==ac_m.u) return n-size[ac_m.u];
 72       return n-size[ab_m.u]-size[ac_m.u];
 73   }
 74   else{
 75     if (ab_m.type==2) swap(ab_m,ac_m);
 76     int tmp=rmq_query(ab_m.u,ac_m.u);
 77     if (tmp==ab_m.u) return size[ab_m.u]-size[ac_m.u];
 78     return size[ab_m.u];
 79   }
 80 }
 81 int main()
 82 {
 83   int a,b,c,ab,bc,ac,T,m,i;
 84   scanf("%d",&T);
 85   while (T--)
 86   {
 87     scanf("%d",&n);
 88     now=0;
 89     memset(head,-1,sizeof(head));
 90     for (i=1;i<n;i++)
 91     {
 92       scanf("%d%d",&a,&b);
 93       add(a,b); add(b,a);
 94     }
 95     dfs(1,-1,0);
 96     rmq_build(n);
 97     scanf("%d",&m);
 98     while (m--)
 99     {
100       scanf("%d%d%d",&a,&b,&c);
101       ab=rmq_query(a,b),ac=rmq_query(a,c),bc=rmq_query(b,c);
102       printf("%d %d %d\n",
103           cal(a,b,c,ab,ac),cal(b,a,c,ab,bc),cal(c,a,b,ac,bc));
104     }
105   }
106   return 0;
107 }
View Code

题目链接:http://acm.hdu.edu.cn/search.php?field=problem&key=2013+Asia+Regional+Changchun+&source=1&searchmode=source

posted on 2015-02-09 01:41  xiao_xin  阅读(167)  评论(0编辑  收藏  举报

导航