TYVJ 1744 逆序对数(加强版)

思路:

与a有关的逆序对数=(在a之前出现的比a大的数+在a之后出现的比a小的数)/2

当我们删除a时,减少的是 与a有关的逆序对数,当我们把a的位置填充b时增加的是 与b有关的逆序对数,可以用树状数组求

这样我们相处了nmlogK的算法,显然是不能承受的(K=500000)

但是我们发现当a相同时我们可以将所有的b在logn的时间内算出来,这样复杂度就成了(m+n)logK了

完全可以承受~

 

PS:不知道为什么我和别人用一样的思路我的代码怎么比他们快3倍啊。。求解释。。(卖萌。。。。)

 

View Code
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 
  6 #define N 500010
  7 
  8 using namespace std;
  9 
 10 struct P
 11 {
 12     int a,b,id;
 13 }p[N];
 14 
 15 int c[N],n,m,a[N],fw[N],inc[N];
 16 __int64 ans[N],anssum;
 17 
 18 inline bool cmp(const P &x,const P &y)
 19 {
 20     return x.a<y.a;
 21 }
 22 
 23 inline int lowbit(int x)
 24 {
 25     return x&-x;
 26 }
 27 
 28 inline int getsum(int x)
 29 {
 30     int rt=0;
 31     while(x)
 32     {
 33         rt+=c[x];
 34         x-=lowbit(x);
 35     }
 36     return rt;
 37 }
 38 
 39 inline void updata(int x,int dt)
 40 {
 41     while(x<N)
 42     {
 43         c[x]+=dt;
 44         x+=lowbit(x);
 45     }
 46 }
 47 
 48 void read()
 49 {
 50     scanf("%d%d",&n,&m);
 51     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
 52     
 53     for(int i=1;i<=n;i++)
 54     {
 55         fw[i]=i-1-getsum(a[i]);
 56         updata(a[i],1);
 57     }
 58     memset(c,0,sizeof c);
 59     
 60     for(int i=n;i>=1;i--)
 61     {
 62         fw[i]+=getsum(a[i]-1);
 63         updata(a[i],1);
 64         anssum+=fw[i];
 65     }
 66     memset(c,0,sizeof c);
 67     
 68     for(int i=1;i<=m;i++)
 69     {
 70         scanf("%d%d",&p[i].a,&p[i].b);
 71         p[i].id=i;
 72     }
 73     
 74     sort(p+1,p+1+m,cmp);
 75 }
 76 
 77 void go()
 78 {
 79     int sp=1;
 80     for(int i=1;i<=n;i++)
 81     {
 82         while(p[sp].a==i)
 83         {
 84             inc[p[sp].id]=i-1-getsum(p[sp].b);
 85             sp++;
 86         }
 87         updata(a[i],1);
 88     }
 89     memset(c,0,sizeof c);
 90     
 91     sp=m;
 92     for(int i=n;i>=1;i--)
 93     {
 94         while(p[sp].a==i)
 95         {
 96             inc[p[sp].id]+=getsum(p[sp].b-1);
 97             sp--;
 98         }
 99         updata(a[i],1);
100     }
101     anssum/=2;
102     for(int i=1;i<=m;i++)
103         ans[p[i].id]=anssum-fw[p[i].a]+inc[p[i].id];
104     printf("%I64d\n",anssum);
105     for(int i=1;i<=m;i++)
106         printf("%I64d\n",ans[i]);
107 }
108 
109 int main()
110 {
111     read();
112     go();
113     //system("pause");
114     return 0;
115 }

转载于:https://www.cnblogs.com/proverbs/archive/2012/10/04/2711334.html

基于bert实现关系三元组抽取python源码+据集+项目说明.zip基于bert实现关系三元组抽取python源码+据集+项目说明.zip基于bert实现关系三元组抽取python源码+据集+项目说明.zip基于bert实现关系三元组抽取python源码+据集+项目说明.zip基于bert实现关系三元组抽取python源码+据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值