NOI2014

听说14,15年的题是最简单的,然后除了提答以外的不那么水的题都是以前讲过、做过的,都比较好想到,但是我实现起来却有各种Bug,也完全不能在5h里AC。。。太弱了

[NOI2014]起床困难综合症

纯粹的送分题,每一位分开枚举选1和选0的答案,一样就选0,否则能选就选答案大的,不能就选0.

然后我脑残把返回((a[i]&(1LL<<j))>0)写成了返回(a[i]&(1LL<<j))wa了一发。。

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=1e5+7;
15 typedef long long LL; 
16 typedef double db;
17 using namespace std;
18 int n,m,a[N],power[32];
19 char o[N][5];
20 
21 template<typename T> void read(T &x) {
22     char ch=getchar(); x=0; T f=1;
23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24     if(ch=='-') f=-1,ch=getchar();
25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27 
28 int calc(int pos,int v) {
29     For(i,1,n) {
30         int w=(a[i]&power[pos])?1:0;
31         if(o[i][0]=='A') v&=w;
32         if(o[i][0]=='O') v|=w;
33         if(o[i][0]=='X') v^=w;
34     }
35     return v;
36 }
37 
38 //#define DEBUG
39 int main() {
40 #ifdef DEBUG
41     freopen("1.in","r",stdin);
42     //freopen(".out","w",stdout);
43 #endif
44     read(n); read(m);
45     power[0]=1;
46     For(i,1,29) power[i]=(power[i-1]<<1);
47     For(i,1,n) {
48         scanf("%s",o[i]);
49         read(a[i]);
50     }
51     int now=0,ans=0;
52     Rep(i,29,0) {
53         if(now+power[i]>m) {
54             int x=calc(i,0);
55             if(x) ans+=power[i];
56             continue;
57         }
58         int rs1=calc(i,0),rs2=calc(i,1);
59         if(rs1==rs2) ans+=rs1*power[i];
60         else if(rs1>rs2) ans+=power[i];
61         else {
62             ans+=power[i];
63             now+=power[i];
64         }
65     }
66     printf("%d\n",ans);
67     return 0;
68 }
View Code

[NOI2014]魔法森林

听讲和讲过多次的题了。

传送门

【NOI2014】消除游戏

这题我不会啊。。我可以手算第一个点。。

据说标解是什么拆成12*12的格子然后咋个搞一下。。

 

[NOI2014]动物园

随便看了看觉得是水题,就不小心费了一个多小时

先没用脑袋写了一些什么kmp的假算法,随便就×掉,然后一直没想清楚。

然后想了下SA可以搞。但是看看数据是O(N)的啊。

又重新想kmp,一道水题想这么久,真是被自己蠢哭了。

求一个kmp的nxt数组,然后一个cnt数组表示从这一位沿着nxt跳包括自己在内可以跳多少步,pr数组表示沿着nxt跳到的第一个前后缀不重合的地方,那么答案就是num[x]=cnt[pr[x]-1]

如果nxt前后缀不重合则pr=nxt否则pr从pr[i-1]开始找即可。

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=1000007,mod=1e9+7;
15 typedef long long LL; 
16 typedef double db;
17 using namespace std;
18 int T,n;
19 char s[N];
20 
21 template<typename T> void read(T &x) {
22     char ch=getchar(); x=0; T f=1;
23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24     if(ch=='-') f=-1,ch=getchar();
25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27 
28 LL sum;
29 int nxt[N],pr[N],num[N],cnt[N];
30 void make_nxt() {
31     int k=0;
32     For(i,0,n-1) num[i]=0,cnt[i]=1,pr[i]=0;
33     For(i,1,n-1) {
34         while(k&&s[i]!=s[k]) k=nxt[k-1];
35         if(s[i]==s[k]) k++;
36         nxt[i]=k;
37         pr[i]=k;
38         if(k) cnt[i]+=cnt[k-1];
39         if(pr[i]&&pr[i]*2>i+1) {
40             pr[i]=pr[i-1];
41             if(pr[i-1]*2==i) pr[i]=nxt[pr[i]-1];
42             while(pr[i]&&s[pr[i]]!=s[i]) pr[i]=nxt[pr[i]-1];
43             if(s[pr[i]]==s[i]) pr[i]++;
44         }
45         //int kk=k;
46         //while(kk&&kk*2>i+1) kk=nxt[kk-1]; 
47         if(pr[i]) num[i]+=cnt[pr[i]-1];
48     }
49 }
50 
51 //#define DEBUG
52 int main() {
53 #ifdef DEBUG
54     freopen("1.in","r",stdin);
55     //freopen(".out","w",stdout);
56 #endif
57     read(T);
58     while(T--) {
59         scanf("%s",s);
60         n=strlen(s);
61         sum=1;
62         make_nxt();
63         For(i,0,n-1) sum=sum*(num[i]+1)%mod;
64         printf("%lld\n",sum);
65     }
66     return 0;
67 }
View Code

[NOI2014]随机数生成器

第一反应是树套树,差点都开始打了发现我是个大sb……

容易发现贪心策略,每次从当前可以选的位置(若干个角相连的矩形)中选最大的一个,然后它所在的矩形就会被它分成两个。

可以用set维护这些矩形,开个数组维护每个位置还能不能选,然后从小往大选,每次选后把新不能选的部分标记

然后有点卡常

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(register int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(register int i=(a);i>=(b);i--)
14 #define FormyLove return 0
15 const int N=5000*5000+7;
16 typedef long long LL; 
17 typedef double db;
18 using namespace std;
19 LL x,a,b,c,d;
20 int T[N],tid[N],n,m,q,ans[N];
21 bool ok[N];
22 
23 template<typename T> void read(T &x) {
24     char ch=getchar(); x=0; T f=1;
25     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
26     if(ch=='-') f=-1,ch=getchar();
27     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
28 }
29 
30 struct node {
31     int lx,ly,rx,ry;
32     node(int lx,int ly,int rx,int ry):lx(lx),ly(ly),rx(rx),ry(ry){}
33     friend bool operator <(const node &A,const node&B) { 
34         return A.rx<B.rx; 
35     }
36 };
37 set<node>s;
38 inline int get_x(int y) { return y%m?y/m+1:y/m; }
39 inline int get_y(int y) { return y%m==0?m:y%m; }
40 inline int get_id(int x,int y) { return (x-1)*m+y; }
41 inline int in(node a,int xx,int yy) { return xx>=a.lx&&xx<=a.rx&&yy>=a.ly&&yy<=a.ry; }
42 
43 //#define DEBUG
44 int main() {
45 #ifdef DEBUG
46     freopen("1.in","r",stdin);
47     //freopen(".out","w",stdout);
48 #endif
49     read(tid[0]); read(a); read(b); read(c); read(d);
50     read(n); read(m); read(q);
51     For(i,1,n*m) T[i]=i;
52     For(i,1,n*m) tid[i]=((LL)a*tid[i-1]%d*tid[i-1]%d+b*tid[i-1]%d+c)%d;
53     For(i,1,n*m) {
54         swap(T[i],T[tid[i]%i+1]);
55     }
56     For(i,1,q) {
57         int u,v; 
58         read(u); read(v);
59         swap(T[u],T[v]);
60     }
61     For(i,1,n*m) {
62         tid[T[i]]=i; 
63         ok[i]=1;
64     }
65     s.insert(node(1,1,n,m));
66     For(i,1,n*m) if(ok[tid[i]]) {
67         ans[++ans[0]]=i;
68         ok[tid[i]]=0;
69         int xx=get_x(tid[i]),yy=get_y(tid[i]);
70         node t1=*s.lower_bound(node(xx,yy,xx,yy));
71         if(!in(t1,xx,yy)) t1=*++s.lower_bound(node(xx,yy,xx,yy));
72         if((xx==t1.lx&&yy==t1.ly)||(xx==t1.rx&&yy==t1.ry));
73         else {
74             s.erase(t1);
75             node t2=t1,t3=t1;
76             For(j,t1.lx,xx-1) For(k,yy+1,t1.ry) ok[get_id(j,k)]=0;
77             For(j,xx+1,t1.rx) For(k,t1.ly,yy-1) ok[get_id(j,k)]=0;
78             t2.rx=xx; t2.ry=yy; t3.lx=xx; t3.ly=yy;
79             if(t2.lx==t2.rx||t2.ly==t2.ry) {
80                 For(i,t2.lx,t2.rx) For(j,t2.ly,t2.ry) {
81                     int id=get_id(i,j);
82                     if(ok[id]) ok[id]=0,ans[++ans[0]]=T[id];
83                 }
84             }
85             else s.insert(t2);
86             if(t3.lx==t3.rx||t3.ly==t3.ry) {
87                 For(i,t3.lx,t3.rx) For(j,t3.ly,t3.ry) {
88                     int id=get_id(i,j);
89                     if(ok[id]) ok[id]=0,ans[++ans[0]]=T[id];
90                 }
91             }
92             else s.insert(t3);
93         }
94     }
95     sort(ans+1,ans+ans[0]+1);
96     //unique(ans+1,ans+ans[0]+1);
97     For(i,1,n+m-1) printf("%d ",ans[i]); puts("");
98     FormyLove;
99 }
View Code

 

[NOI2014]购票

之前轩神讲过,刚好最近想找这道题,结果它自己找上门了。

F[x]=min(a[x]*(R[x]-R[y])+f[y]);

经过平面上一点(R[y],f[y])斜率为a[i]的直线的纵截距a[x]*R[y]+f[y]

那么可以对每个点从它到它上面能拓展到的最远点维护一个右下凸壳

维护的凸壳要支持删除和添加

回滚莫队+set似乎可以做到sqrt(n)logn,

如果用线段树呢

附上轩神详细的题解

然后因为两个智障错误使我de了一整个晚上的bug

 一是应该是一个区间满后建它前一个区间,而不是看一个区间后一个满没满再建它自己。。这样根本啥都没建,比暴力还慢

二是我建凸包的时候把while写成了for。。。

一整个晚上就没有了

唯一让我欣慰的是我发现有一位仁兄和我同时在做这道题,也做了一晚上,刷了一整版的提交记录,然后我们在相邻的两分钟内A了它

大概就是“同是天涯沦落人,相逢何必曾相识”吧

虽然这位大佬好像比我强很多很多很多

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #include<map>
 12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 14 const int N=4e5+7;
 15 typedef long long LL; 
 16 typedef double db;
 17 using namespace std;
 18 int n,t,fa[N],sta[N],top;
 19 LL f[N],R[N],lim[N],a[N],b[N];
 20 
 21 template<typename T> void read(T &x) {
 22     char ch=getchar(); x=0; T f=1;
 23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 24     if(ch=='-') f=-1,ch=getchar();
 25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 26 }
 27 
 28 int ecnt,fir[N],nxt[N],to[N];
 29 LL val[N];
 30 void add(int u,int v,LL w) {
 31     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
 32 }
 33 
 34 #define lc x<<1
 35 #define rc ((x<<1)|1)
 36 #define mid ((l+r)>>1)
 37 int ok[N<<2],full[N<<2],emp[N<<2],tp[N],qr;
 38 vector<int>ham[N<<2];
 39 
 40 #define LD long double
 41 #define eps 1e-7
 42 LD cross(int a1,int a2,int b1,int b2) { return (LD)(R[a1]-R[a2])*(f[b1]-f[b2])-(LD)(R[b1]-R[b2])*(f[a1]-f[a2]); }
 43 
 44 void get_ham(int x,int l,int r) {
 45     qr=0;
 46     if(x==515) {
 47         int debug=1;
 48     }
 49     For(i,l,r) {
 50         while(qr>1&&cross(sta[i],tp[qr-1],tp[qr],tp[qr-1])>-eps) qr--;
 51         tp[++qr]=sta[i];
 52     }
 53     ham[x].clear();
 54     For(i,1,qr) ham[x].push_back(tp[i]);
 55     ok[x]=1;
 56 }
 57 
 58 int xl[N<<2],xr[N<<2];
 59 void build(int x,int l,int r) {
 60     xl[x]=l; xr[x]=r;
 61     if(l==r) return;
 62     build(lc,l,mid); build(rc,mid+1,r);
 63 }
 64 
 65 void update(int x,int l,int r,int pos,int F) {
 66     if(l==r) { 
 67         if(F) full[x]=1,emp[x]=0; 
 68         else emp[x]=1,full[x]=0; 
 69         return ; 
 70     }
 71     if(pos<=mid) update(lc,l,mid,pos,F);
 72     else update(rc,mid+1,r,pos,F);
 73     full[x]=(full[lc]&full[rc]);
 74     emp[x]=(emp[lc]&emp[rc]);
 75     ok[x]=(ok[x]&full[x]);
 76     if(l!=1&&!ok[x-1]&&full[x]) get_ham(x-1,xl[x-1],xr[x-1]);
 77 }
 78 
 79 LL calc(int x,int y) {
 80     LL d=R[x]-R[y];
 81     return a[x]*d+b[x]+f[y];
 82 }
 83 
 84 LL find(int x,int ll,int rr,int now) {
 85     if(x==515&&ll==1174&&rr==1563&&now==2136) {
 86         int debug=1;
 87         int up=ham[x].size();
 88         For(i,0,up-1) {
 89             if(i) {
 90                 db k=(db)(f[ham[x][i]]-f[ham[x][i-1]])/(db)(R[ham[x][i]]-R[ham[x][i-1]]);
 91                 if(k<0) {
 92                     int debug=1;
 93                 }
 94             }
 95             LL rs=calc(now,ham[x][i]);
 96             rs=rs;
 97         }
 98     }
 99     if(ll==rr) return calc(now,sta[ll]);
100     int l=1,r=ham[x].size();
101     while(l<r) {
102         if(l+1==r) {
103             LL rs1=calc(now,ham[x][l-1]),rs2=calc(now,ham[x][r-1]);
104             return min(rs1,rs2);
105         }
106         LL rs1=calc(now,ham[x][mid-2]),rs2=calc(now,ham[x][mid-1]),rs3=calc(now,ham[x][mid]);
107         if(rs1>=rs2&&rs3>=rs2) return rs2;
108         if(rs1<=rs2&&rs2<=rs3) r=mid-1;
109         else l=mid+1;
110     }
111     return calc(now,ham[x][l-1]);
112 }
113 
114 LL qry(int x,int l,int r,int ql,int qr,int now) {
115     if(ql>qr) return -1;
116     if(x==515&&l==1174&&r==1563&&ql==1&&qr==2135&&now==2136) {
117         int debug=1;
118     }
119     if(l>=ql&&r<=qr&&(ok[x]||l==r)) 
120         return find(x,l,r,now);
121     if(qr<=mid) return qry(lc,l,mid,ql,qr,now);
122     if(ql>mid) return qry(rc,mid+1,r,ql,qr,now);
123     return min(qry(lc,l,mid,ql,qr,now),qry(rc,mid+1,r,ql,qr,now));
124 }
125 
126 int H[N];
127 LL st[N][20];
128 int stf[N][20];
129 void solve(int x) {
130     if(x==2136) {
131         int debug=1;
132     }
133     int y=x;
134     LL now=0;
135     Rep(i,18,0) if(stf[y][i]&&now+st[y][i]<=lim[x]) {
136         now+=st[y][i];
137         y=stf[y][i];
138     }
139     int l=H[y],r=H[x];
140     f[x]=qry(1,1,n,l,r-1,x);
141 }
142 
143 void dfs(int x) {
144     H[x]=H[fa[x]]+1;
145     stf[x][0]=fa[x];
146     For(i,1,18) {
147         stf[x][i]=stf[stf[x][i-1]][i-1];
148         st[x][i]=(st[x][i-1]+st[stf[x][i-1]][i-1]);
149     }
150     if(x!=1)  solve(x); //f[x]+=R[x]*a[x]+b[x]; }
151     sta[++top]=x;
152     update(1,1,n,H[x],1);
153     for(int i=fir[x];i;i=nxt[i]) {
154         R[to[i]]=R[x]+val[i];
155         st[to[i]][0]=val[i];
156         dfs(to[i]);
157     }
158     top--;
159     update(1,1,n,H[x],0);
160 }
161 
162 //#define DEBUG
163 int main() {
164 #ifdef DEBUG
165     freopen("ticket.in","r",stdin);
166     freopen("ticket.out","w",stdout);
167 #endif
168     read(n); read(t);
169     For(i,2,n) {
170         LL w;
171         read(fa[i]); read(w); 
172         add(fa[i],i,w);
173         read(a[i]); read(b[i]); read(lim[i]);
174     }
175     build(1,1,n);
176     dfs(1);
177     For(i,2,n) printf("%lld\n",f[i]);
178     return 0;
179 }
View Code

猜你喜欢

转载自www.cnblogs.com/Achenchen/p/9011331.html
今日推荐