题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1706
trick:关于正数和负数的整除问题,正数整除是自动向下取整的,但负数是向上取整的
即13/3=4.3 ->4 但-13/3=-4.3 ->-4
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <queue> #include <vector> #define maxn 32500 #define maxe 11000 #define INF 0x3f3f3f #define lson l,mid,u<<1 #define rson mid+1,r,u<<1|1 #define ll_int long long int using namespace std; ll_int seg[maxn<<2]; ll_int pau[maxn<<2]; //bool flag[maxn<<2]; ll_int initsum; void PushUp(int u){ seg[u] = seg[u<<1] + seg[u<<1|1]; } void PushDown(int l,int r,int u){ if(pau[u]){ int mid = (l + r)/2; pau[u<<1] = pau[u<<1|1] = pau[u]; seg[u<<1] = (ll_int)(mid - l + 1) * pau[u]; seg[u<<1|1] = (ll_int)(r - mid) * pau[u]; pau[u] = 0; } } void build(int l,int r,int u){ seg[u] = 0; pau[u] = 0; if(l == r){ scanf("%lld",&seg[u]); initsum += seg[u]; return; } int mid = (l + r)/2; build(lson); build(rson); PushUp(u); } void Update(int L,int R,int num,int l,int r,int u){ if(L <= l && r <= R){ pau[u] = num; seg[u] = (ll_int)(r - l + 1)* num; return; } PushDown(l,r,u); int mid = (l + r)/2; if(L <= mid) Update(L,R,num,lson); if(R > mid) Update(L,R,num,rson); PushUp(u); //要记住啊 } ll_int Query(int L,int R,int l,int r,int u){ if(L <= l && r <= R){ return seg[u]; } PushDown(l,r,u); int mid = (l + r)/2; ll_int ret = 0; if(L <= mid) ret += Query(L,R,lson); if(R > mid) ret += Query(L,R,rson); return ret; } void print(int l,int r,int u){ if(l == r){ if(l == 1) printf("%lld",seg[u]); else printf(" %lld",seg[u]); return; } PushDown(l,r,u); int mid = (l + r)/2; print(lson); print(rson); } int main(){ // freopen("input.txt","r",stdin); int n,m; while(scanf("%d%d",&n,&m) == 2){ initsum = 0; build(1,n,1); for(int i=1;i<=m;i++){ int a,b; scanf("%d%d",&a,&b); ll_int sum = Query(a,b,1,n,1); int ave = sum/(b-a+1); if(sum > 0 && seg[1] <= initsum){ //为正的UP; if(sum % (b-a+1)) ave++; } else if(sum < 0 && seg[1] > initsum){ //为负的down; if(sum % (b-a+1)) ave--; } Update(a,b,ave,1,n,1); } print(1,n,1); printf(" "); } }