bzoj2038小z的袜子

用平面曼哈顿距离最小生成树或者莫队算法都可以吖QwQ~

然而显然后者更好写(逃~)

莫队怎么写就看图吧QwQ~

话说我一开始没开long long然后拍了3000组没拍出错交上去Wa了QAQ

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define int long long
using namespace std;
const int Mx=50010;
struct Node { int l,r,num; } que[Mx];
bool cmp1 (Node a,Node b) { return a.l<b.l; }
bool cmp2 (Node a,Node b) { return a.r<b.r; }
int n,m,c[Mx],num[Mx],ans[Mx],ans1[Mx][2];
inline int gcd (int a,int b) { int tmp; while(a>0) tmp=b%a,b=a,a=tmp;  return b; }
signed main()
{
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
    for(int i=1;i<=m;i++) { scanf("%lld%lld",&que[i].l,&que[i].r);if(que[i].l>que[i].r) swap(que[i].l,que[i].r); }
    for(int i=1;i<=m;i++) que[i].num=i;
    sort(que+1,que+1+m,cmp1);
    for(int i=1;i<=m;i+=sqrt(m)) sort(que+i,que+min(m,i+(int)sqrt(m)),cmp2);
    for(int i=1;i<=m;i++)
    {
        if(i%(int)sqrt(m)==1||i==1)
        {
            memset(num,0,sizeof(num));
            for(int j=que[i].l;j<=que[i].r;j++) num[c[j]]++;
            for(int j=0;j<=n;j++) ans[i]+=num[j]*(num[j]-1)/2;
        }
        else
        {
            for(int j=que[i-1].l,to=que[i].l;j!=to;)
            {
                if(j<to) ans[i]-=num[c[j]]-1,num[c[j]]--,j++;
                else ans[i]+=num[c[j-1]],num[c[j-1]]++,j--;
            }
            for(int j=que[i-1].r,to=que[i].r;j!=to;)
            {
                if(j<to) ans[i]+=num[c[j+1]],num[c[j+1]]++,j++;
                else ans[i]-=num[c[j]]-1,num[c[j]]--,j--;
            }
            ans[i]+=ans[i-1];
        }
        int div=gcd(ans[i],(que[i].r-que[i].l+1)*(que[i].r-que[i].l)/2);
        if(que[i].r==que[i].l||ans[i]==0) ans1[que[i].num][0]=0,ans1[que[i].num][1]=1;
        else ans1[que[i].num][0]=ans[i]/div,ans1[que[i].num][1]=(que[i].r-que[i].l+1)*(que[i].r-que[i].l)/(div*2);
    }
    for(int i=1;i<=m;i++) printf("%lld/%lld\n",ans1[i][0],ans1[i][1]);
    return 0;
}
时间: 2024-10-29 19:05:56

bzoj2038小z的袜子的相关文章

bzoj2038 小z的袜子 (莫队)

题目大意 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同色的袜子会很尴尬. 你的任务便是告诉小Z,他有多大的概率抽到两只颜色相同的袜子.当然,小Z希望这个概率尽量高,所以他可能会询问多个(L,R)以方便自己选择. 100

BZOJ2038 小z的袜子

今天新学习了莫队算法,感觉好神,离线的询问好像都可以用莫队. 要不是坑爹的HNOI2016考了两道莫队题,才不得不来入这个坑   题目大意就是给一些数,然后每次询问一段区间,问从这个区间中抽走两个数,抽到相同的数的概率   把询问离线下来,然后按照左端点所在块的编号来排序,若在同一个块则以右端点编号排序(有点像分块) 然后我每次暴力处理一下一个询问,之后利用这一次的结果,往前或者往后拓展,把处在同一个快的全部都可以处理掉(期望复杂度:O(1)) 最终可以达到O(N^1.5)的复杂度 复杂度证明的

bzoj-2038 小Z的袜子 hose

题意: 给出一个长度为n的序列,每次询问一个区间[l,r]: 查询在这个区间中取出两个数恰好相等的概率: 每个数大小在[0,n]内,概率用既约分数表示: 题解: 考虑一个区间的答案,显然是合法方案数/取数的所有可能: 也就是 ∑C[同种数字个数][2]/C[r-l+1][2]: 但是这个东西对一次询问的处理复杂度是O(r-l+1)的: 那么考虑上莫队算法,处理这样的区间问题: 很容易发现每次修改边界可以做到O(1)完成: void update(int x,int op) { now-=C[s[

bzoj2038 小Z的袜子(hose)——莫队算法

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 就是莫队算法: 先写了个分块,惨WA: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; int const maxn=

bzoj 2038 小Z的袜子(hose)(莫队算法)

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 11542  Solved: 5166[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命--具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两

BZOJ 2038: [2009国家集训队]小Z的袜子(hose)

2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 7676  Solved: 3509[Submit][Status][Discuss] Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命……具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只

清橙A1206 小Z的袜子(莫队算法)

A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB 总提交次数:744   AC次数:210   平均分:44.44 将本题分享到: 查看未格式化的试题   提交   试题讨论 试题来源 2010中国国家集训队命题答辩 问题描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到N编号,然后从编号L到R(L 尽管小Z并不在意两只袜子是不是

【BZOJ】2038: [2009国家集训队]小Z的袜子(hose)

[算法]莫队 [题解] BZOJ 2038 2009国家集训队 小Z的袜子(hose) 莫队算法 莫队--讲稿? 施工中--

BZOJ 2038: [2009国家集训队]小Z的袜子(hose) ( 莫队 )

莫队..先按sqrt(n)分块, 然后按块的顺序对询问排序, 同块就按右端点排序. 然后就按排序后的顺序暴力求解即可. 时间复杂度O(n1.5) ------------------------------------------------------------------------------ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 50009; int N,