zoukankan      html  css  js  c++  java
  • jxoi2017

    题解:

    并不知道题目顺序就按照难度排序了

    [JXOI2017]加法

    这是一道很简单的贪心

    最小值最大二分答案

    然后我们可以从左向右考虑每一个位置

    如果他还需要+A

    我们就从能覆盖它的区间中挑一个最右的

    正确性比较显然

    暴力是n^2logn*T的 可能比较虚

    会发现覆盖操作可以用线段树维护,查询最右可以使用堆

    n*logn^2*T

     [JXOI2017]颜色

    写的复杂了。。

    正解比较简单

    枚举右端点i,确定左端点j的可行位置

    我们会发现,

    对于maxv<=i,那么maxv>=j>=minv是不可行的

    对于maxv>i,那么1<=j<=minv是不可行的

    于是问题就变成了区间+1,区间-1,查询为0的个数

    网上好像都是利用这个是1-x的所以变成从左到右枚举然后优先队列解决的

    其实我们可以通过维护最小值个数,最小值来直接实现

    我的方法是对于每一种颜色

    我们可行的方案是在两个颜色空当之中,或者1个在最左边,1个在最右边

    于是问题变成了n次覆盖一个矩形,最后查询矩形中为k的个数(其实查为0就和上面一样了)

    注意区间2-1这样的是不符合的 所以可以先给不符合的-1

    然后我们可以利用扫描线+线段树解决

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    #define me(x) memset(x,0,sizeof(x))
    #define mid ((h+t)/2)
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
      return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; 
    }
    template<class T>IL void read(T &x)
    {
      rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
      while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
    }
    const int N=4e5+10;
    const int N2=N*4;
    int cnt;
    struct re{
      int a,b,c,d;
    }p[N*5];
    int maxa[N2],lazy[N2],data[N2],a[N];
    vector<int> ve[N];
    IL void change(int h1,int t1,int h2,int t2,int k)
    {
      p[++cnt].a=h1,p[cnt].b=h2,p[cnt].c=t2,p[cnt].d=k;
      p[++cnt].a=t1+1,p[cnt].b=h2,p[cnt].c=t2,p[cnt].d=-k;
    }
    IL bool cmp(re x,re y)
    {
      return(x.a<y.a);
    }
    void build(int x,int h,int t)
    {
      maxa[x]=0; data[x]=t-h+1; lazy[x]=0;
      if (h==t) return;
      build(x*2,h,mid); build(x*2+1,mid+1,t);
    }
    int cnt2=0;
    void insert(int x,int h,int t,int h1,int t1,int k)
    {
      if (h1>t1) return;
      if (h1<=h&&t<=t1)
      {
        maxa[x]+=k; lazy[x]+=k; return;
      }
      if (lazy[x])
      {
        maxa[x*2]+=lazy[x]; maxa[x*2+1]+=lazy[x];
        lazy[x*2]+=lazy[x]; lazy[x*2+1]+=lazy[x];
        lazy[x]=0;
      }
      if (h1<=mid) insert(x*2,h,mid,h1,t1,k);
      if (mid<t1) insert(x*2+1,mid+1,t,h1,t1,k);
      int t11=maxa[x*2],t22=maxa[x*2+1];
      if (t11<t22) maxa[x]=t22,data[x]=data[x*2+1];
      else if (t11>t22) maxa[x]=t11,data[x]=data[x*2];
      else maxa[x]=t11,data[x]=data[x*2+1]+data[x*2];
    }
    int main()
    {
      int T,n;
      read(T);
      rep(ttt,1,T)
      {
        read(n);
        rep(i,1,n) ve[i].clear();
        int m=0;
        rep(i,1,n)
        {
          read(a[i]);
          m=max(a[i],m);
          ve[a[i]].push_back(i);
        }
        int k=m; cnt=0;
        rep(i,1,m)
        {
          if (!ve[i].size())
          { 
            k--; continue;
          }
          change(1,ve[i][0],ve[i][ve[i].size()-1],n,1);
          int tmp=(int)(ve[i].size())-2;
          rep(j,0,tmp)
            change(ve[i][j]+1,ve[i][j+1]-1,ve[i][j]+1,ve[i][j+1]-1,1);
          change(1,ve[i][0]-1,1,ve[i][0]-1,1);
          change(ve[i][ve[i].size()-1]+1,n,ve[i][ve[i].size()-1]+1,n,1);
        }
        rep(i,2,n)
        {
          change(i,i,1,i-1,-1);
        }
        sort(p+1,p+cnt+1,cmp);
        ll ans=0;
        build(1,1,n);
        rint j=1;
        rep(i,1,n)
        {
          while (j<=cnt&&p[j].a<=i) insert(1,1,n,p[j].b,p[j].c,p[j].d),j++;
          if (maxa[1]==k) ans+=data[1];
        }
        printf("%lld
    ",ans);
      }
      return 0; 
    }
  • 相关阅读:
    文件格式——gff格式
    文件格式——fastq格式
    Java 8 新特性:1-函数式接口
    10分钟学会JAVA注解(annotation)
    spring MVC 乱码问题
    Tomcat 连接池详解
    DBCP连接池配置参数说明
    spring 事务无效解决方法
    spring mvc 存取值
    使用Criteria 实现两表的左外连接,返回根对象
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9510183.html
Copyright © 2011-2022 走看看