BZOJ 2308 莫队入门经典

题目链接  https://www.lydsy.com/JudgeOnline/problem.php?id=2038

参考博客  https://www.cnblogs.com/Paul-Guderian/p/6933799.html

      https://www.cnblogs.com/hzf-sbit/p/4056874.html 

解析  C(2,n)=n*(n-1)/2=(n*n-n)/2

    分子就是∑C(sum[i],2) ( i 是区间内的颜色  sum[i] 是区间内i颜色的数量)公式真难写。。。 还是看第二篇博客吧。

 1 /**************************************************************
 2     Problem: 2038
 3     User: 1071532391
 4     Language: C++
 5     Result: Accepted
 6     Time:1708 ms
 7     Memory:5604 kb
 8 ****************************************************************/
 9  
10 #include <bits/stdc++.h>
11 #define pb push_back
12 #define mp make_pair
13 #define fi first
14 #define se second
15 #define all(a) (a).begin(), (a).end()
16 #define fillchar(a, x) memset(a, x, sizeof(a))
17 #define huan printf("\n");
18 #define debug(a,b) cout<<a<<" "<<b<<" ";
19 using namespace std;
20 typedef long long ll;
21 const int maxn=1e5+10,inf=0x3f3f3f3f;
22 const ll mod=1e9+7;
23 ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
24 int n,m,unit,col[maxn],be[maxn];
25 ll sum[maxn],ans=0;
26 struct node
27 {
28     int l,r,id;
29     ll ans1,ans2;
30 }a[maxn];
31 int cmp1(node a,node b)
32 {
33     if(be[a.l]==be[b.l])
34         return a.r<b.r;
35     return a.l<b.l;
36 }
37 int cmp2(node a,node b)
38 {
39     return a.id<b.id;
40 }
41 ll S(ll x) {return x*x;}
42 void revise(int x,int add)
43 {
44     ans-=S(sum[col[x]]);
45     sum[col[x]]+=add;
46     ans+=S(sum[col[x]]);
47 }
48 int main()
49 {
50     scanf("%d%d",&n,&m);
51     unit=sqrt(n);
52     for(int i=1;i<=n;i++)
53     {
54         scanf("%d",col+i);be[i]=i/unit+1;
55     }
56     for(int i=1;i<=m;i++)
57     {
58         scanf("%d%d",&a[i].l,&a[i].r);
59         a[i].id=i;
60     }
61     sort(a+1,a+m+1,cmp1);
62     int l=1,r=0;
63     for(int i=1;i<=m;i++)
64     {
65         while(l<a[i].l)revise(l,-1),l++;
66         while(l>a[i].l)revise(l-1,1),l--;
67         while(r>a[i].r)revise(r,-1),r--;
68         while(r<a[i].r)revise(r+1,1),r++;
69         if(a[i].l==a[i].r)
70         {
71             a[i].ans1=0,a[i].ans2=1;
72             continue;
73         }
74         a[i].ans1=ans-(a[i].r-a[i].l+1);
75         a[i].ans2=1ll*(a[i].r-a[i].l+1)*(a[i].r-a[i].l);
76         ll gcd_=gcd(a[i].ans1,a[i].ans2);
77         a[i].ans1/=gcd_;a[i].ans2/=gcd_;
78     }
79     sort(a+1,a+m+1,cmp2);
80     for(int i=1;i<=m;i++)
81         printf("%lld/%lld\n",a[i].ans1,a[i].ans2);
82     return 0;
83 }
84 

 

转载于:https://www.cnblogs.com/stranger-/p/9408928.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值