noip模擬題 ----飛
阿新 • • 發佈:2018-12-12
本題的空間限制是32MB
可以發現實際上就是要求有多少對線段產生了相交
又因為y軸上是升序,所以就是求產生的序列中,有多少個逆序對
可以發現因為資料生成的方法是有跡可循的,我們可以將值域分塊
每a的長度就是一個塊,可以通過一個塊的貢獻統計其他塊的貢獻,就減少了空間和時間複雜度
用樹狀陣列來維護這個東西
#include<bits/stdc++.h> #pragma GCC optimize(2) #define RG register using namespace std; int shu,n,a,mod,maxa,piece,pos,pd[100005]; long long all,now,another; long long ans,tree[100005]; inline void modify(int x) { x++; for(RG int i=x;i<=1e5;i+=(i&-i)) tree[i]++; } inline long long query(int x) { x++; RG long long ans=0; for(RG int i=x;i>=1;i-=(i&-i)) ans+=tree[i]; return ans; } int get(int x) { return x/a+1; } inline int moc(int x) { if(x>=mod) return x-mod; return x; } int main() { freopen("fly.in","r",stdin); freopen("fly.out","w",stdout); cin>>n>>shu>>a>>mod; int pre=shu; modify(shu%a); int pos=get(shu)-1,remain=1,tot=1; for(int i=2;i<=n;i++) { shu+=a; if(shu>=mod) { shu-=mod; tot++; modify(shu); remain=query(shu); } int now=get(shu); int temp=tot*(now-1)+remain; if(shu%a>=pre%a) temp-=min(now,pos); else temp-=min(now-1,pos); ans+=i-temp; } cout<<ans; return 0; }