HYSBZ - 2038 小Z的袜子(hose) (莫队)
中文题面
题解:莫队+组合数,注意LL啊啊啊
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <queue> #include <vector> #include <cstring> #include <iomanip> #include <set> #include<ctime> //CLOCKS_PER_SEC #define se second #define fi first #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define Pii pair<int,int> #define Pli pair<ll,int> #define ull unsigned long long #define pb push_back #define fio ios::sync_with_stdio(false);cin.tie(0) const int N=5e4+10; const ull base=163; const int INF=0x3f3f3f3f; using namespace std; int a[N]; struct node { int l,r,id; }Q[N]; int pos[N]; int L=1,R=0; ll ans=0; pair<ll,ll>res[N]; int n,q; ll mp[N]; bool cmp(node x,node y){ if(pos[x.l]==pos[y.l])return x.r<y.r; return pos[x.l]<pos[y.l]; } ll gcd(ll a,ll b){ if(b==0)return a; else return gcd(b,a%b); } void del(int x){ ans-=mp[a[x]]*(mp[a[x]]-1)/2; mp[a[x]]--; ans+=mp[a[x]]*(mp[a[x]]-1)/2; } void add(int x){ ans-=mp[a[x]]*(mp[a[x]]-1)/2; mp[a[x]]++; ans+=mp[a[x]]*(mp[a[x]]-1)/2; } int main(){ scanf("%d%d",&n,&q); int sz=sqrt(n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); pos[i]=i/sz; } for(int i=1;i<=q;i++){ scanf("%d%d",&Q[i].l,&Q[i].r); Q[i].id=i; } sort(Q+1,Q+1+q,cmp); for(int i=1;i<=q;i++){ while(L>Q[i].l){ L--; add(L); } while(L<Q[i].l){ del(L); L++; } while(R<Q[i].r){ R++; add(R); } while(R>Q[i].r){ del(R); R--; } if(L==R){Q[i].l=0,Q[i].r=1;continue;} ll k=gcd(ans,1LL*(Q[i].r-Q[i].l+1)*(Q[i].r-Q[i].l)/2); res[Q[i].id].fi=ans/k; res[Q[i].id].se=1LL*(Q[i].r-Q[i].l+1)*(Q[i].r-Q[i].l)/2/k; } for(int i=1;i<=q;i++){ printf("%lld/",res[i].fi); if(res[i].fi==0)printf("1\n"); else printf("%lld\n",res[i].se); } return 0; }