【数据结构】【杂题】jzoj 6342.Tiny Counting

较为简单的一个计数题目。


 

Description
 
Input
Output
 
Sample Input
4
1 4 3 2
Sample Output
3

我们可以将这个题目拆开来想:

1.不考虑重复点,求全部情况:

  假设情况1为

  

 

  共p种。 

 

  情况2为

 

  

 

 

  共q种,那么答案ans=qp。

 

2.考虑重复的情况:

 

  重复的情况,无非就是两组共用了同一个端点。

 

  设点(i,si),那么当a=d时,有(c<a<b&&sa<sb&&sa<sc)

 

  在坐标系上就是这样表示的:

 

  

 

   将绿色部分的点数*蓝色部分的点数就得到了这部分的结果。

  其余类似,可以发现ans=pq-(a+b)(c+d),你可以认为abcd表示四个象限。

要离散化,用树状数组搞搞就能出来了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll N=2e5+10;
 5 ll n_,n,ans; 
 6 ll b[N],aa[N],bb[N],cc[N],dd[N];
 7 struct poll{
 8     ll size,idx;
 9 }a[N];
10 ll arr[N];
11 ll lb(ll x){return x&-x;}
12 void add(ll x){for(;x<=n;x+=lb(x))arr[x]++;}
13 ll pre(ll x){ll ans_=0;for(;x;x-=lb(x))ans_+=arr[x];return ans_;}
14 bool cmp(poll x,poll y){
15     return x.size<y.size;
16 }
17 ll read(){
18     ll x=0,f=1;
19     char c=getchar();
20     while(!isdigit(c)){
21         if(c=='-') f=-1;
22         c=getchar(); 
23     } 
24     while(isdigit(c)){
25         x=x*10+c-'0';
26         c=getchar();
27     }
28     return x*f;
29 }
30 int main(){
31     freopen("a.in","r",stdin);
32     freopen("a.out","w",stdout);
33     n_=read();
34     for(ll i=1;i<=n_;i++){
35         a[i].size=read();
36         a[i].idx=i;
37     } 
38     sort(a+1,a+n_+1,cmp);
39     a[0].size=-1;
40     for(ll i=1;i<=n_;i++){
41         if(a[i].size>a[i-1].size) ++n;
42         b[a[i].idx]=n;
43     }
44     ll t1=0,t2=0;
45     for(ll i=1;i<=n_;i++){
46         bb[i]=pre(b[i]-1);
47         dd[i]=pre(n)-pre(b[i]);
48         t1+=bb[i],t2+=dd[i];
49         add(b[i]);
50     }
51     ans=t1*t2;
52     memset(arr,0,sizeof(arr)); 
53     for(ll i=n_;i>=1;i--){
54         cc[i]=pre(b[i]-1);
55         aa[i]=pre(n)-pre(b[i]);
56         ans-=(aa[i]+bb[i])*(cc[i]+dd[i]);
57         add(b[i]);
58     }
59     printf("%lld",ans);
60     return 0;
61 } 

 

转载于:https://www.cnblogs.com/Nelson992770019/p/11483072.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值