题目:点击此处
思路:求出每个区间中从每种颜色中选两个 的种类数的和
如果和为零输出0/1
否则输出 和/ ( (r-l+1)*(r-l)/2 ) 最简形式
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <algorithm> #define ll long long using namespace std; const int maxn=1e6+5; struct node { ll l,r,i; }pos[maxn]; ll n,block,q,l,r,ans=0; ll mp[maxn],c[maxn],a[maxn]; struct an{ ll zi,mu; }answer[maxn]; bool cmp(node a,node b) { if(a.l/block!=b.l/block) return a.l/block<b.l/block; return a.r<b.r; } void add(ll x) { ans+=mp[a[x]]; mp[a[x]]++; } void remov1e(ll x) { mp[a[x]]--; ans-=mp[a[x]]; } int main() { scanf("%lld%lld",&n,&q);block=sqrt(1.0*n); for(ll i=1;i<=n;i++) scanf("%lld",&a[i]); for(ll i=1;i<=q;i++) { scanf("%lld%lld",&pos[i].l,&pos[i].r); pos[i].i=i; } sort(pos+1,pos+1+q,cmp); ll cl=pos[1].l,cr=cl-1; for(ll i=1;i<=q;i++) { l=pos[i].l,r=pos[i].r; while(cl<l) { remov1e(cl); cl++; } while(cl>l) { add(cl-1); cl--; } while(cr<r) { add(cr+1); cr++; } while(cr>r) { remov1e(cr); cr--; } ll zi=ans; if(zi==0) { answer[pos[i].i].zi=0; answer[pos[i].i].mu=1; } else { ll mu=(r-l+1)*(r-l)/2; ll g=__gcd(zi,mu); zi/=g;mu/=g; answer[pos[i].i].zi=zi; answer[pos[i].i].mu=mu; } } for(ll i=1;i<=q;i++) cout<<answer[i].zi<<"/"<<answer[i].mu<<endl; return 0; }