NC20120. [HNOI2017]大佬
描述
人们总是难免会碰到大佬。他们趾高气昂地谈论凡人不能理解的算法和数据结构,走到任何一个地方,大佬的气场就能让周围的人吓得瑟瑟发抖,不敢言语。 你作为一个 OIER,面对这样的事情非常不开心,于是发表了对大佬不敬的言论。 大佬便对你开始了报复,你也不示弱,扬言要打倒大佬。
现在给你讲解一下什么是大佬,大佬除了是神犇以外,还有着强大的自信心,自信程度可以被量化为一个正整数 , 想要打倒一个大佬的唯一方法是摧毁 Ta 的自信心,也就是让大佬的自信值等于 0(恰好等于 0,不能小于 0)。 由于你被大佬盯上了,所以你需要准备好 天来和大佬较量,因为这 天大佬只会嘲讽你动摇你的自信,到了第 天,如果大佬发现你还不服,就会直接虐到你服,这样你就丧失斗争的能力了。
你的自信程度同样也可以被量化,我们用 来表示你的自信值上限。
在第 天(),大佬会对你发动一次嘲讽,使你的自信值减小 ,如果这个时刻你的自信值小于 了,那么你就丧失斗争能力,也就失败了(特别注意你的自信值为 的时候还可以继续和大佬斗争)。 在这一天, 大佬对你发动嘲讽之后,如果你的自信值仍大于等于 ,你能且仅能选择如下的行为之一:
还一句嘴,大佬会有点惊讶,导致大佬的自信值 减小 。
做一天的水题,使得自己的当前自信值增加 , 并将新自信值和自信值上限 比较,若新自信值大于 ,则新自信值更新为 。例如, , 当前自信值为 , 若,则新自信值为 ,若 ,则新自信值为 。
让自己的等级值 加 。
让自己的讽刺能力 乘以自己当前等级 ,使讽刺能力 更新为 。
怼大佬,让大佬的自信值 减小 。并在怼完大佬之后,你自己的等级 自动降为 ,讽刺能力 降为 。由于怼大佬比较掉人品,所以这个操作只能做不超过 次。
特别注意的是,在任何时候,你不能让大佬的自信值为负,因为自信值为负,对大佬来说意味着屈辱,而大佬但凡遇到屈辱就会进化为更厉害的大佬直接虐飞你。在第 天,在你被攻击之前,你的自信是满的(初始自信值等于自信值上限 ), 你的讽刺能力 是 , 等级是 。
现在由于你得罪了大佬,你需要准备和大佬正面杠,你知道世界上一共有 个大佬,他们的嘲讽时间都是 天,而且第 天的嘲讽值都是 。不管和哪个大佬较量,你在第 天做水题的自信回涨都是 。 这 个大佬中只会有一个来和你较量( 天里都是这个大佬和你较量),但是作为你,你需要知道对于任意一个大佬,你是否能摧毁他的自信,也就是让他的自信值恰好等于 。和某一个大佬较量时,其他大佬不会插手。
输入描述
第一行三个正整数 。分别表示有 天和 个大佬,你的自信上限为 。
接下来一行是用空格隔开的 个数,其中第 个表示 。
接下来一行是用空格隔开的 个数,其中第 个表示 。
接下来 行,每行一个正整数,其中第 行的正整数 表示第 个大佬的初始自信值。
输出描述
共 行,如果能战胜第 个大佬(让他的自信值恰好等于 ),那么第k行输出 ,否则输出。
示例1
输入:
10 20 100 22 18 15 16 20 19 33 15 38 49 92 14 94 92 66 94 1 16 90 51 4 5 9 338 5222 549 7491 9 12 3288 3 1 2191 833 3 6991 2754 3231 360 6
输出:
1 1 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1
C++14(g++5.4) 解法, 执行用时: 318ms, 内存消耗: 28772K, 提交时间: 2019-10-29 22:08:10
// luogu-judger-enable-o2 //It is made by M_sea #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #include <queue> #define re register using namespace std; template<typename T> inline void chkmax(T& x,T y) { if (y>x) x=y; } template<typename T> inline void chkmin(T& x,T y) { if (y<x) x=y; } inline int read() { int X=0,w=1; char c=getchar(); while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); } while (c>='0'&&c<='9') X=X*10+c-'0',c=getchar(); return X*w; } const int N=100+10; const int MOD=1000007; const int inf=0x3f3f3f3f; struct hash_table { struct oho { int u,v,nxt; } e[2000000]; int head[MOD+5],cnt; inline void insert(int u,int v) { int tmp=(1ll*u*100+v)%MOD; e[++cnt]=(oho){u,v,head[tmp]},head[tmp]=cnt; } inline int query(int u,int v) { int tmp=(1ll*u*100+v)%MOD; for (re int i=head[tmp];i;i=e[i].nxt) if (e[i].u==u&&e[i].v==v) return 1; return 0; } } H; int n,m,mc,d,maxc; int a[N],w[N],c[N]; int f[N][N]; struct node { int s,F,L; }; struct state { int s,F; } S[2000000]; bool operator <(state a,state b) { if (a.F==b.F) return a.s<b.s; else return a.F<b.F; } int top=0; inline void bfs() { queue<node> Q; Q.push((node){1,1,0}); while (!Q.empty()) { node x=Q.front(); Q.pop(); int s=x.s,F=x.F,L=x.L; if (s<d) { Q.push((node){s+1,F,L+1}); //level up if (L>1&&1ll*F*L<=1ll*maxc&&!H.query(F*L,s+1)) { Q.push((node){s+1,F*L,L}); //atk up S[++top]=(state){s+1,F*L}; H.insert(F*L,s+1); } } } } int main() { n=read(),m=read(),mc=read(); for (re int i=1;i<=n;++i) a[i]=read(); for (re int i=1;i<=n;++i) w[i]=read(); for (re int i=1;i<=m;++i) c[i]=read(),chkmax(maxc,c[i]); //dp for (re int i=1;i<=n;++i) for (re int j=a[i];j<=mc;++j) { chkmax(f[i][j-a[i]],f[i-1][j]+1); chkmax(f[i][min(mc,j-a[i]+w[i])],f[i-1][j]); } for (re int i=1;i<=n;++i) for (re int j=0;j<=mc;++j) chkmax(d,f[i][j]); //bfs bfs(); //solve sort(S+1,S+top+1); for (re int i=1;i<=m;++i) { if (c[i]<=d) { puts("1"); continue; } int ans=0,mn=inf; for (re int j=top,k=1;j>=1;--j) { while (k<top&&S[j].F+S[k].F<=c[i]) chkmin(mn,S[k].s-S[k].F),++k; if (mn+S[j].s-S[j].F+c[i]<=d) { ans=1; break; } if (S[j].F<=c[i]&&c[i]-S[j].F+S[j].s<=d) { ans=1; break; } } printf("%d\n",ans); } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 516ms, 内存消耗: 31496K, 提交时间: 2020-04-03 11:59:25
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define ll long long #define RG register #define MAX 111 #define ft(i) zt[i].first #define sd(i) zt[i].second inline int read() { RG int x=0,t=1; RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if(ch=='-') t=-1,ch=getchar(); while(ch<='9'&&ch>='0') x=x*10+ch-48,ch=getchar(); return x*t; } int f[MAX][MAX]; int n,m,MC,Day,a[MAX],w[MAX],C[MAX]; struct Node { int i,F,L; }; pair<int,int> zt[1111111]; int tot,mx; int MOD=1000007; struct Hash { struct Line { int x,y,next; }e[1111111]; int h[1000007+1],cnt; void Add(int x,int y) { int pos=(1ll*x*101+y)%MOD; e[++cnt]=(Line){x,y,h[pos]}; h[pos]=cnt; } bool Query(int x,int y) { int pos=(1ll*x*101+y)%MOD; for(int i=h[pos];i;i=e[i].next) if(e[i].x==x&&e[i].y==y) return true; return false; } }Map; void BFS() { queue<Node> Q; Q.push((Node){1,1,0}); while(!Q.empty()) { Node u=Q.front(); Q.pop(); if(u.i==Day) continue; Q.push((Node){u.i+1,u.F,u.L+1}); if(u.L>1&&1ll*u.F*u.L<=1ll*mx&&!Map.Query(u.F*u.L,u.i+1)) { Q.push((Node){u.i+1,u.F*u.L,u.L}); zt[++tot]=make_pair(u.F*u.L,u.i+1); Map.Add(u.F*u.L,u.i+1); } } } int main() { n=read(); m=read(); MC=read(); for(int i=1;i<=n;++i) a[i]=read(); for(int i=1;i<=n;++i) w[i]=read(); for(int i=1;i<=m;++i) mx=max(mx,C[i]=read()); for(int i=1;i<=n;++i) for(int j=a[i];j<=MC;++j) { f[i][j-a[i]]=max(f[i-1][j]+1,f[i][j-a[i]]); f[i][min(j-a[i]+w[i],MC)]=max(f[i-1][j],f[i][min(j-a[i]+w[i],MC)]); } for(int i=1;i<=n;++i) for(int j=1;j<=MC;++j) Day=max(Day,f[i][j]); BFS(); sort(&zt[1],&zt[tot+1]); for(int i=1;i<=m;++i) { if(C[i]<=Day) { puts("1"); continue; } bool fl=false; int mm=1e9; for(int j=tot,k=1;j;--j) { while(k<tot&&ft(k)+ft(j)<=C[i]) mm=min(mm,sd(k)-ft(k)),++k; if(mm+C[i]-ft(j)<=Day-sd(j)) { fl=true; break; } if(ft(j)<=C[i]&&C[i]-ft(j)<=Day-sd(j)) { fl=true; break; } } fl? puts("1"):puts("0"); } return 0; }