51nod 1617 奇偶数组
回来看一眼51nod,发现自己掉到rank4了,赶紧切道题回rank3。
一眼不会做,这种东西应该慢慢找规律吧……然后看到数据范围其实比较小,应该是单次log的,那是不是可以分治啊。
#include<cstdio> #include<algorithm> #define ll long long using namespace std; ll n,l,r,L,R;int m,MOD; int M(int x){while(x>=MOD)x-=MOD;while(x<0)x+=MOD;return x;} int f(ll x){x%=MOD;return (x*(x+1)>>1)%MOD;} struct na{ int sum,n; na(int _sum=0,int _n=0):sum(_sum),n(_n){}; }; na operator + (na a,na b){return na(M(a.sum+b.sum),M(a.n+b.n));} na cgl(na a){return na(M(a.sum*2-a.n),a.n);} na cgr(na a){return na(M(a.sum*2),a.n);} na mmh(ll n,ll l,ll r,ll L,ll R){ if (L>n||L>R||l>n||r<1||R<0) return na(0,0); if (l<1) l=1;if (r>n) r=n;if (R>n) R=n; if (l==1&&r==n) return na(M(f(R)-f(L-1)),(R-L+1)%MOD); ll mid=(n+1)>>1; na MMH=cgl(mmh(mid,l,r,(L>>1)+1,R+1>>1))+cgr(mmh(n-mid,l-mid,r-mid,L+1>>1,R>>1)); return MMH; } int main(){ scanf("%lld%d%d",&n,&m,&MOD); while(m--){ scanf("%lld%lld%lld%lld",&l,&r,&L,&R); printf("%d\n",mmh(n,l,r,L,R).sum); } }