7.16训练 2013ACM-ICPC杭州全国邀请赛

我写了A和G,G似乎是一道通过率比较低的题目,数据结构C没写出来。

总共过了4题

A

一个机器人在长度为n的环上,有m个指令,发出后机器人随机顺时针或逆时针走若干步,问最终机器人落在一个区间的概率。

n<=200 m<=10^6

题解:

简单概率DP,但是卡时间和空间。

4000ms时限,3900ms通过。

很难让人不怀疑有其他做法(事实上确实想到了O(n^3+m)的做法,但是有精度限制,如果可以对概率取模,就能做了

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 double f[2][201],g[500];
 4 int main()
 5 {
 6     int n,m,l,r;
 7     while (1)
 8     {
 9         scanf("%d%d%d%d",&n,&m,&l,&r);
10         if (n==0&&m==0&&l==0&&r==0) break;
11         f[0][1]=1;
12         for (int i=1;i<=n;i++) g[i]=0;
13         int w=1;
14         for (int i=1;i<=m;i++)
15         {
16             int x;
17             scanf("%d",&x);
18             for (int j=1;j<=n;j++)
19             {
20                 int k1=(j+x-1)%n+1;
21                 int k2=(j+(n-x)-1)%n+1;
22                 f[w][j]=f[1-w][k1]*0.5+f[1-w][k2]*0.5;
23             }
24             w=1-w;
25         }
26         double ans=0;
27         for (int i=l;i<=r;i++) ans+=f[m&1][i];
28         for (int j=1;j<=n;j++) f[0][j]=0;
29         printf("%.4lf\n",ans); 
30     }
31      
32 }

 

G

给一棵图的dfs树和一些不在dfs树上的边,定义简单环为只有一条边不在树上的环,选出一些树边,使得原图中所有简单环都至少被选中一条边。

n<=2000 m<=20000

题解:

一个图取出dfs树之后,除了树边,只剩下返祖边。

单独考虑一条从根到叶子的路径,可以从树上退化下来,就是一个点覆盖区间问题,上树之后做法也是差不多的。

值得吐槽的是,数据有重边...这很令人难受。

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=2e3+10;
 4 const int M=4e4+10;
 5 int tot=0,tot1=0,ans=0,n,tt=0;
 6 int he[N],ne[M],t[M];
 7 int he1[N],ne1[M],t1[M];
 8 int a[M],b[M];
 9 int dep[N],f[N];
10 int pp[N][N];
11 void link(int x,int y)
12 {
13     tot++;
14     ne[tot]=he[x];
15     he[x]=tot;
16     t[tot]=y;    
17 }
18 void link1(int x,int y)
19 {    
20     tot1++;
21     ne1[tot1]=he1[x];
22     he1[x]=tot1;
23     t1[tot1]=y;    
24 }
25 void dfs(int x,int y)
26 {
27     dep[x]=dep[y]+1;
28     for (int i=he1[x];i;i=ne1[i]) if (t1[i]!=y) dfs(t1[i],x);
29 }
30 void dfs1(int x,int y)
31 {
32     for (int i=he1[x];i;i=ne1[i]) if (dep[t1[i]]==dep[x]+1&&t1[i]!=y) 
33     {
34         dfs1(t1[i],x);
35         f[x]=max(f[x],f[t1[i]]);
36     }
37     if (f[x]+1==dep[x]&&f[x])
38     {
39         ans++;
40         f[x]=0;    
41     }
42 }
43 int main()
44 {    
45     int m;
46     while (1)
47     {
48         scanf("%d%d",&n,&m);
49         tt++;
50         if (n==0&&m==0) break;
51         for (int i=1;i<=n;i++) he[i]=he1[i]=0,f[i]=0,dep[i]=0;
52         tot=tot1=0;
53         for (int i=1;i<n;i++)
54         {
55             int x,y;
56             scanf("%d%d",&x,&y);
57             link1(x,y);
58             link1(y,x);
59         }
60         dfs(1,0);
61         for (int i=n;i<=m;i++)
62         {
63             scanf("%d%d",&a[i],&b[i]); 
64             if (dep[a[i]]<dep[b[i]]) swap(a[i],b[i]);
65             if (abs(dep[a[i]]-dep[b[i]])!=1) f[a[i]]=max(f[a[i]],dep[b[i]]);
66         }
67         ans=0;
68         dfs1(1,0);
69         //if (f[1]==1) ans++;
70         printf("%d\n",ans);
71     }
72 }

 

 

补题:

C

三个操作:区间加,区间乘,区间赋值

三种询问:区间和,区间平方和,区间立方和

n<=10^5 m<=10^5

题解:

打三种标记,标记有等级,赋值标记为最高级,影响另外两种标记。

乘标记为次高级,影响加标记。

线段树即可

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=1e5+10;
  4 const int mo=1e4+7;
  5 int s[4][N*4],b1[N*4],b2[N*4],b3[N*4];
  6 void build(int rt,int l,int r)
  7 {
  8     s[1][rt]=s[2][rt]=s[3][rt]=b1[rt]=b3[rt]=0;
  9     b2[rt]=1;
 10     if (l==r) return;
 11     int mid=l+r>>1;
 12     build(rt<<1,l,mid);
 13     build(rt<<1|1,mid+1,r);    
 14 }
 15 void up(int rt)
 16 {
 17     s[1][rt]=(s[1][rt<<1]+s[1][rt<<1|1])%mo;
 18     s[2][rt]=(s[2][rt<<1]+s[2][rt<<1|1])%mo;
 19     s[3][rt]=(s[3][rt<<1]+s[3][rt<<1|1])%mo;
 20 }
 21 void c1(int rt,int l,int r,int c)
 22 {
 23     s[3][rt]=(s[3][rt]+3*s[1][rt]%mo*c%mo*c%mo+3*s[2][rt]%mo*c%mo+1ll*(r-l+1)*c%mo*c%mo*c%mo)%mo;
 24     s[2][rt]=(s[2][rt]+2*s[1][rt]%mo*c%mo+1ll*(r-l+1)*c%mo*c%mo)%mo;
 25     s[1][rt]=(s[1][rt]+1ll*(r-l+1)*c%mo)%mo;
 26     b1[rt]=(b1[rt]+c)%mo;    
 27 }
 28 void c2(int rt,int l,int r,int c)
 29 {
 30     s[3][rt]=s[3][rt]*c%mo*c%mo*c%mo;
 31     s[2][rt]=s[2][rt]*c%mo*c%mo;
 32     s[1][rt]=s[1][rt]*c%mo;
 33     b1[rt]=b1[rt]*c%mo;
 34     b2[rt]=b2[rt]*c%mo;    
 35 }
 36 void c3(int rt,int l,int r,int c)
 37 {
 38     s[3][rt]=1ll*c*c%mo*c%mo*(r-l+1)%mo;
 39     s[2][rt]=1ll*c*c%mo*(r-l+1)%mo;
 40     s[1][rt]=1ll*c*(r-l+1)%mo;
 41     b1[rt]=0;
 42     b2[rt]=1;
 43     b3[rt]=c;
 44 }
 45 void push(int rt,int l,int r)
 46 {
 47     int mid=l+r>>1;
 48     if (b3[rt]) 
 49     {
 50         c3(rt<<1,l,mid,b3[rt]);
 51         c3(rt<<1|1,mid+1,r,b3[rt]);
 52         b3[rt]=0;    
 53     }
 54     if (b2[rt]!=1)
 55     {
 56         c2(rt<<1,l,mid,b2[rt]);
 57         c2(rt<<1|1,mid+1,r,b2[rt]);
 58         b2[rt]=1;    
 59     }
 60     if (b1[rt])
 61     {
 62         c1(rt<<1,l,mid,b1[rt]);
 63         c1(rt<<1|1,mid+1,r,b1[rt]);
 64         b1[rt]=0;    
 65     }
 66 }
 67 void m1(int rt,int l,int r,int x,int y,int z)
 68 {
 69     if (l>=x&&r<=y)
 70     {
 71         c1(rt,l,r,z);
 72         return;
 73     }
 74     push(rt,l,r);
 75     int mid=l+r>>1;
 76     if (x<=mid) m1(rt<<1,l,mid,x,y,z);
 77     if (y>mid) m1(rt<<1|1,mid+1,r,x,y,z);
 78     up(rt);
 79 }
 80 void m2(int rt,int l,int r,int x,int y,int z)
 81 {
 82     if (l>=x&&r<=y)
 83     {
 84         c2(rt,l,r,z);
 85         return;
 86     }
 87     push(rt,l,r);
 88     int mid=l+r>>1;
 89     if (x<=mid) m2(rt<<1,l,mid,x,y,z);
 90     if (y>mid) m2(rt<<1|1,mid+1,r,x,y,z);
 91     up(rt);
 92 }
 93 void m3(int rt,int l,int r,int x,int y,int z)
 94 {
 95     if (l>=x&&r<=y)
 96     {
 97         c3(rt,l,r,z);
 98         return;
 99     }
100     push(rt,l,r);
101     int mid=l+r>>1;
102     if (x<=mid) m3(rt<<1,l,mid,x,y,z);
103     if (y>mid) m3(rt<<1|1,mid+1,r,x,y,z);
104     up(rt);
105 }
106 int qq(int rt,int l,int r,int x,int y,int z)
107 {
108     if (l>=x&&r<=y) return s[z][rt];
109     push(rt,l,r);
110     int mid=l+r>>1,ret=0;
111     if (x<=mid) ret=ret+qq(rt<<1,l,mid,x,y,z);
112     if (y>mid) ret=ret+qq(rt<<1|1,mid+1,r,x,y,z);
113     return ret%mo;
114 }
115 int main()
116 {
117     int n,m;
118     while (1)
119     {
120         scanf("%d%d",&n,&m);
121         if (n==0&&m==0) break;
122         build(1,1,n);
123         for (int i=1;i<=m;i++)
124         {
125             int tp,l,r,x;
126             scanf("%d%d%d%d",&tp,&l,&r,&x);
127             if (tp==1) m1(1,1,n,l,r,x);
128             else if (tp==2) m2(1,1,n,l,r,x);
129             else if (tp==3) m3(1,1,n,l,r,x);
130             else printf("%d\n",qq(1,1,n,l,r,x)%mo);    
131         }
132     }
133 }

 

posted @ 2021-07-16 16:39  praying_cqf  阅读(80)  评论(0)    收藏  举报