zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:统计(树状数组+乱搞)

    题目传送门(内部题120)


    输入格式

      第一行,两个正整数$n,m$。
      第二行,$n$个正整数$a_1,a_2,...,a_n$,保证$1leqslant a_ileqslant n$,可能存在相同值。
      第三行,$m$个正整数$j_1,j_2,...,j_m$,保证$1leqslant j_kleqslant n$。


    输出格式

      第一行,第一个整数表示操作前的逆序对数量,接下来$m$个整数表示每次操作后的逆序对数量。


    样例

    样例输入:

    6 2
    1 3 4 2 6 1
    2 3

    样例输出:

    6 3 1


    数据范围与提示

    样例解释:

      第一次操作:由$1 3 4 2 6 1$变为$1 1 4 2 6 3$。
      第二次操作:由$1 1 4 2 6 3$变为$1 1 2 3 6 4$。
      加粗标记的是这次操作影响到的数。

    数据范围:

      对于$40\%$的数据,$1leqslant n,mleqslant 200$。
      对于$60\%$的数据,$1leqslant n,mleqslant 2,000$。
      对于$80\%$的数据,$1leqslant n,mleqslant 20,000$。
      对于$100\%$的数据,$1leqslant n,mleqslant 200,000,1leqslant a_ileqslant n,1leqslant j_kleqslant n$。


    题解

    $Theta(nlog n)$求逆序对在此不再赘述。

    打开大样例,发现很多都是一样的,于是考虑乱搞……

    发现,如果在前面某一次操作时动了某个位置,如果现在还动这个位置则对逆序对个数是没有影响的(相当与没动),直接输出上一次的结果即可。

    时间复杂度:$Theta(n^2log n)$。

    期望得分:$60$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    int a[200001],top;
    int e[200001],b[200001];
    int tr[200010];
    bool vis[200001];
    long long ans;
    int lowbit(int x){return x&-x;}
    void add(int x){for(int i=x;i;i-=lowbit(i))tr[i]++;}
    int ask(int x){int res=0;for(int i=x;i<=n+1;i+=lowbit(i))res+=tr[i];return res;}
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    	for(int i=1;i<=n;i++){ans+=ask(a[i]+1);add(a[i]);}
    	printf("%lld ",ans);
    	while(m--)
    	{
    		int k;
    		scanf("%d",&k);
    		if(vis[k]){printf("%lld ",ans);continue;}
    		if(!ans){puts("0");continue;}
    		ans=top=0;
    		for(int i=1;i<=n;i++)tr[i]=0;
    		for(int i=k;i<=n;i++)
    			if(a[i]<=a[k])
    			{
    				vis[i]=1;
    				e[++top]=a[i];
    				b[top]=i;
    			}
    		sort(e+1,e+top+1);
    		for(int i=1;i<=top;i++)a[b[i]]=e[i];
    		for(int i=1;i<=n;i++){ans+=ask(a[i]+1);add(a[i]);}
    		printf("%lld ",ans);
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    Python使用SMTP模块、email模块发送邮件
    harbor搭建及使用
    ELK搭建-windows
    ELK技术栈之-Logstash详解
    【leetcode】1078. Occurrences After Bigram
    【leetcode】1073. Adding Two Negabinary Numbers
    【leetcode】1071. Greatest Common Divisor of Strings
    【leetcode】449. Serialize and Deserialize BST
    【leetcode】1039. Minimum Score Triangulation of Polygon
    【leetcode】486. Predict the Winner
  • 原文地址:https://www.cnblogs.com/wzc521/p/11796134.html
Copyright © 2011-2022 走看看