zoukankan      html  css  js  c++  java
  • 糖糖别胡说,我真的不是签到题目

    传送门

    题解: 核心就是满足条件,i<j and a[i]!=a[j] and b[i]<b[j] ; 另外有个附加属性,有一些发功的时间 i 第i秒会给在第i秒及以前出现的b[i]+1,

    用一个sum[i]数组表示在此时间受到发功影响的次数的总和。那么问题就是变为 在i<j的条件下,b[i]+sum[j]-sum[i-1]<b[j]+sum[j]-sum[j-1];

    两边同时去掉sum[j],即b[i]-sum[i-1]<b[j]-sum[j-1];ps:发功时间是第i秒的话,前面i-1秒的元素不会被影响。

    只有两个组别,0和1,可以用a[i]^1来表达不同组。从后往前扫描,记录每组的最大值,与不同组的比较即可。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5;
    int a[maxn];
    int b[maxn];
    int sum[maxn];
    int ans;
    int main(){
        int t,n,m,f;cin>>t;
        while(t--){
            ans=0;
            fill(sum,sum+maxn,0);
            fill(a,a+maxn,0);
            fill(b,b+maxn,0);
            cin>>n>>m;
            for(int i=1;i<=n;i++){
                scanf("%d%d",&a[i],&b[i]);
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&f);
                sum[f]++;
            }
            for(int i=1;i<=n;i++){
                sum[i]+=sum[i-1];
                b[i]-=sum[i-1];
            }
            int ans=n;
            int c[2];c[0]=-0x3f3f3f;c[1]=-0x3f3f3f;
            for(int i=n;i>=1;i--){
                if(b[i]<c[a[i]^1])ans--;
                c[a[i]]=max(c[a[i]],b[i]);
            }
            cout<<ans<<endl;
        }
            return 0;
    }

     

  • 相关阅读:
    布局管理器
    下拉列表框
    时间,日期选择器
    关于部分基本控件的使用
    关于Activity
    什么时候修改class
    JavaScript Break 和 Continue 语句
    JavaScript While 循环
    JavaScript For 循环
    JavaScript Switch 语句
  • 原文地址:https://www.cnblogs.com/mohari/p/12984937.html
Copyright © 2011-2022 走看看