题解: 题意容易理解错 实质上这个题就是2种操作
1.单点修改
2.问是否每次操作能否选取c个大于等于1的 然后能否进行s次
首先很显然的 如果大于等于s的数量大于等于c 那么必然可行 如果小于等于c 那我们考虑剩下的总和是否大于等于(c-k)*s 如果大于则可行 否则则不可行
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=1e6+10; const double eps=1e-8; #define ll long long using namespace std; struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;} ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } ll sum1[MAXN],sum2[MAXN],a[MAXN]; vector<ll>vec; int sz; int get_id(int x){return x&(-x);} void update(int x,ll key){for(int i=x;i>0;i-=get_id(i))sum1[i]+=key;} void update2(int x,ll key){for(int i=x;i>0;i-=get_id(i))sum2[i]+=key;} ll Sum1(int x){ll ans=0;for(int i=x;i<=sz;i+=get_id(i))ans+=sum1[i];return ans;} ll Sum2(int x){ll ans=0;for(int i=x;i<=sz;i+=get_id(i))ans+=sum2[i];return ans;} typedef struct node{int op,x;ll y;}node; node d[MAXN]; int main(){ int n,m;n=read();m=read();char ch; vec.pb(0); inc(i,1,m){ scanf(" %c",&ch);d[i].x=read();d[i].y=read();vec.pb(d[i].y); if(ch=='U')d[i].op=1;else d[i].op=2; } sort(vec.begin(),vec.end()); sz=unique(vec.begin(),vec.end())-vec.begin(); for(int i=1;i<=n;i++)a[i]=1; inc(i,1,m){ d[i].y=lower_bound(vec.begin(),vec.begin()+sz,d[i].y)-vec.begin()+1; if(d[i].op==1){update(a[d[i].x],-1),update2(a[d[i].x],-vec[a[d[i].x]-1]),update(d[i].y,1),update2(d[i].y,vec[d[i].y-1]),a[d[i].x]=d[i].y;} else{ ll ans1=Sum1(d[i].y); if(ans1>=d[i].x)puts("TAK"); else { ans1=d[i].x-ans1; ll ans2=Sum2(1)-Sum2(d[i].y); if(ans2>=1LL*ans1*vec[d[i].y-1])puts("TAK"); else puts("NIE"); } } } return 0; }
4378: [POI2015]Logistyka
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 643 Solved: 333
[Submit][Status][Discuss]
Description
维护一个长度为n的序列,一开始都是0,支持以下两种操作:
1.U k a 将序列中第k个数修改为a。
2.Z c s 在这个序列上,每次选出c个正数,并将它们都减去1,询问能否进行s次操作。
每次询问独立,即每次询问不会对序列进行修改。
Input
第一行包含两个正整数n,m(1<=n,m<=1000000),分别表示序列长度和操作次数。
接下来m行为m个操作,其中1<=k,c<=n,0<=a<=10^9,1<=s<=10^9。
Output
包含若干行,对于每个Z询问,若可行,输出TAK,否则输出NIE。
Sample Input
3 8
U 1 5
U 2 7
Z 2 6
U 3 1
Z 2 6
U 2 2
Z 2 6
Z 2 1
U 1 5
U 2 7
Z 2 6
U 3 1
Z 2 6
U 2 2
Z 2 6
Z 2 1
Sample Output
NIE
TAK
NIE
TAK
TAK
NIE
TAK
HINT
鸣谢Claris