P1975 [国家集训队]排队

题目

P1975 [国家集训队]排队

做法

逆序对的题当然想办法用cdq做

交换数列的位置好像不好处理,加个时间轴,把交换操作换成:删、删、加、加(位置可变换)

删的贡献系数为\((-1)\),加的贡献系数为\((1)\),然后丢到树状数组也是根据这个系数,这样可以保证不重复统计同一位置

位置为第一维,时间为第二维,注意排序位置时:\(x_1==x_2\)&&\(y_1<y_2\),因为\(y_1\)放到后面会影响\(x_2\)的

My complete code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
using namespace std;
typedef long long LL;
const LL maxn=1e5;
inline LL Read(){
    LL x(0),f(1);char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;c=getchar();
    }
    while(c>='0'&&c<='9')
        x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}
struct node{
    LL t,x,y,w,id;
    bool operator <(const node &b)const{
        return (x<b.x||(x==b.x&&y<b.y));
    }
}a[maxn],Kl[maxn];
LL n,m,tot,cnt,num,tim;
LL tmp[maxn],val[maxn],tree[maxn],ans[maxn];
inline LL Lowbit(LL x){
    return x&(-x);
}
inline LL Query(LL x){
    LL ret(0);
    for(;x;x-=Lowbit(x))
        ret+=tree[x];
    return ret;
}
inline void Add(LL x,LL c){
    for(;x<=tot;x+=Lowbit(x))
        tree[x]+=c;
}
void Cdq(LL l,LL r){
    if(l==r)
        return;
    LL mid(l+r>>1);
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Add(a[i].y,a[i].w);
        else
            ans[a[i].id]+=a[i].w*(Query(tot)-Query(a[i].y));
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Add(a[i].y,-a[i].w);

    for(LL i=r;i>=l;--i)
        if(a[i].t<=mid)
            Add(a[i].y,a[i].w);
        else
            ans[a[i].id]+=a[i].w*(Query(a[i].y-1));
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Add(a[i].y,-a[i].w);

    LL t1(l-1),t2(mid);
    for(LL i=l;i<=r;++i)
        if(a[i].t<=mid)
            Kl[++t1]=a[i];
        else
            Kl[++t2]=a[i];
    for(LL i=l;i<=r;++i)
        a[i]=Kl[i];
    Cdq(l,mid),Cdq(mid+1,r);
}
int main(){
    n=Read();
    for(LL i=1;i<=n;++i)
        tmp[i]=val[i]=Read();
    sort(tmp+1,tmp+1+n); tot=unique(tmp+1,tmp+1+n)-tmp-1;
    for(LL i=1;i<=n;++i)
        val[i]=lower_bound(tmp+1,tmp+1+tot,val[i])-tmp;
    for(LL i=1;i<=n;++i)
        a[++num]=(node){++tim,i,val[i],1,0};
    m=Read();
    for(LL i=1;i<=m;++i){
        LL x(Read()),y(Read());
        a[++num]=(node){++tim,y,val[x],1,i},
        a[++num]=(node){++tim,x,val[y],1,i},
        a[++num]=(node){++tim,x,val[x],-1,i},
        a[++num]=(node){++tim,y,val[y],-1,i};
        swap(val[x],val[y]);
    }
    sort(a+1,a+1+num);
    Cdq(1,num);
    printf("%lld\n",ans[0]);
    for(LL i=1;i<=m;++i){
        ans[i]+=ans[i-1],
        printf("%lld\n",ans[i]);
    }
    return 0;
}/*
3
130 150 140
2
2 3
1 3
*/

原文地址:https://www.cnblogs.com/y2823774827y/p/10293103.html

时间: 2024-11-09 04:45:46

P1975 [国家集训队]排队的相关文章

[国家集训队] 排队

Luogu Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和. 红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观.设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为: 满足 \(i<j\) 且 \(h_i>h_j\) 的 \((i,j)\) 数量. 幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度.为方便幼

国家集训队2011 happiness

[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. [输入格式] 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学

[国家集训队2010]小Z的袜子

★★★   输入文件:hose.in   输出文件:hose.out   简单对比 时间限制:1 s   内存限制:512 MB [题目描述] 作为一个生活散漫的人,小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并不在意两只

[补档][国家集训队2011]单选错位

题目 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案. 试卷上共有n道单选题,第i道单选题有ai个选项,这ai个选项编号是1,2,3,-,ai,每个选项成为正确答案的概率都是相等的.lc采取的策略是每道题目随机写上1-ai的某个数作为答案选项,他用不了多少时间就能期望做对sigma(1/ai)道题目.gx则是认认真真地做完了这n道题目,可是等他做完的时候时间也所剩无几了,于是他匆忙地把答案抄到答题纸上,没想到抄错位了:第i道题目的答案抄到了答题纸上的第

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

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

cogs 1901. [国家集训队2011]数颜色

Cogs 1901. [国家集训队2011]数颜色 ★★★   输入文件:nt2011_color.in   输出文件:nt2011_color.out   简单对比时间限制:0.6 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题描述] 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令:1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔.2. R P Col 把第P支画笔替换为

【BZOJ 2039】 2039: [2009国家集训队]employ人员雇佣 (最小割)

2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1511  Solved: 728 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j.当然,雇佣每一个经理都需要花费一定

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,