• NOIp2018集训test-10-22 (联考六day2)


    中间值

    两个log肯定会被卡。我用的第一种做法,就是要各种特判要在两个序列都要二分比较麻烦。

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 const int N=1e6+7;
     7 typedef long long LL;
     8 typedef double db;
     9 using namespace std;
    10 int n,m,a[N],b[N];
    11 
    12 template<typename T> void read(T &x) {
    13     char ch=getchar(); x=0; T f=1;
    14     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    15     if(ch=='-') f=-1,ch=getchar();
    16     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    17 }
    18 
    19 #define ANS
    20 int main() {
    21 #ifdef ANS
    22     freopen("median.in","r",stdin);
    23     freopen("median.out","w",stdout);
    24 #endif
    25     read(n); read(m);
    26     For(i,1,n) read(a[i]);
    27     For(i,1,n) read(b[i]);
    28     For(cs,1,m) {
    29         int o,x,y,z,l1,r1,l2,r2;
    30         read(o);
    31         if(o==1) {
    32             read(x); read(y); read(z);
    33             if(!x) a[y]=z;
    34             else b[y]=z;
    35         }
    36         else {
    37             read(l1); read(r1);
    38             read(l2); read(r2);
    39             int len=r1-l1+1+r2-l2+1;
    40             int tot=len/2+1;
    41             int l=1,r=min(tot,r1-l1+1),rs=-1;
    42             while(l<=r) {
    43                 int mid=((l+r)>>1);
    44                 int cnt=tot-mid;
    45                 if(cnt>r2-l2+1) l=mid+1;
    46                 else {
    47                     if((cnt==0||b[l2+cnt-1]<=a[l1+mid-1])&&(l2+cnt>r2||b[l2+cnt]>=a[l1+mid-1])) {
    48                         rs=a[l1+mid-1]; break;
    49                     }
    50                     if(cnt!=0&&b[l2+cnt-1]>a[l1+mid-1]) l=mid+1;
    51                     else r=mid-1;
    52                 }
    53             }
    54             if(rs==-1) {
    55                 swap(l1,l2); swap(r1,r2);
    56                 l=1,r=min(tot,r1-l1+1),rs=-1;
    57                 while(l<=r) {
    58                     int mid=((l+r)>>1);
    59                     int cnt=tot-mid;
    60                     if(cnt>r2-l2+1) l=mid+1;
    61                     else {
    62                         if((cnt==0||a[l2+cnt-1]<=b[l1+mid-1])&&(l2+cnt>r2||a[l2+cnt]>=b[l1+mid-1])) {
    63                             rs=b[l1+mid-1]; break;
    64                         }
    65                         if(cnt!=0&&a[l2+cnt-1]>b[l1+mid-1]) l=mid+1;
    66                         else r=mid-1;
    67                     }
    68                 }
    69             }
    70             printf("%d
    ",rs);
    71         }
    72     }
    73     Formylove;
    74 }
    View Code

    最小值

    dp[i]表示以前i个已经区间分割好了的答案。新加入一个i+1,设i-1前面第一个不大于它的位置为j。

    要么i+1单独分割一个区间,这个区间的左端点可以选择从j+1~i+1,从这一段中选择一个pos使dp[pos-1]最大,用dp[pos-1]+f(a[i+1])来更新dp[i+1]

    要么i+1和之前的一个数为一个区间,那么这个区间的左端点一定在j或者j之前,也就是i+1没有贡献,直接用dp[j]更新dp[i+1]

    我前面不大于我的第一个数用单调栈维护,求dp最大值时用线段树维护即可。

    View Code

    最大值

    我觉得略有点神仙啊。。一道题改了一下午。。。大半个下午都在:题解在说啥???它说的是中文???喵喵喵??

    倒是码出来(虽然比std长了一倍)就直接过了,比较开心。

    题解翻译:

    $E(x)=sum_{i=1}^infty P(x=i)*i$

    $E(x)=sum_{i=1}^infty P(x geq i)$

    $Ans(l,r)=sum_{x=1}^infty P((Max_{i=l}^r v_i) geq x)$

    $ecause Max_{i=l}^r v_i=y_1/y_2/y_3……y_m$

    $ herefore forall xin (y_{i-1}+1,y_i) P((Max_{i=l}^r v_i) geq x)=P((Max_{i=l}^r v_i) geq y_i)$

    $ herefore Ans=sum_{x=1}^m (y_x-y_{x-1})*P((Max_{i=l}^r v_i) geq y_x)$

    $P((Max_{i=l}^r v_i) geq x)=1-P((Max_{i=l}^r v_i) < x)=1-prod_{i=l}^rP(v_i<x)$

    $=1-prod_{i=l}^r(1-P(v_igeq x))$

    $ herefore Ans=sum_{x=1}^m (y_x-y_{x-1})*[1-prod_{i=l}^r(1-P(v_igeq y_x))]$

    当x从x变到x+1时,只有i中包含能量为$y_{x+1}$的魔法石的i的$P(v_igeq y_x)$会发生改变,故x从1~m改变总次数为魔法石的总个数。
    又因为询问区间互相不包含,把询问区间的(l,r)按l排序,包含i的(l,r)一定是一段连续的区间,那么用线段树维护对于当前的x,每个询问区间的$prod_{i=l}^r(1-P(v_igeq y_x))$
    每次维护区间乘一个数的操作,因为$1-P(v_igeq y_x)$会变成0,$y_x$要按从大到小枚举

      1 //Achen
      2 #include<bits/stdc++.h>
      3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
      4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
      5 #define Formylove return 0
      6 const int N=2e5+7,mod=1e9+7;
      7 typedef long long LL;
      8 typedef double db;
      9 using namespace std;
     10 int n,m,q,ls[N],sz;
     11 LL ans,now[N];
     12 
     13 template<typename T> void read(T &x) {
     14     char ch=getchar(); x=0; T f=1;
     15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     16     if(ch=='-') f=-1,ch=getchar();
     17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     18 }
     19 
     20 LL ksm(LL a,LL b) {
     21     LL rs=1,bs=a%mod;
     22     while(b) {
     23         if(b&1) rs=rs*bs%mod;
     24         bs=bs*bs%mod;
     25         b>>=1;
     26     }
     27     return rs;
     28 }
     29 
     30 struct stone {
     31     int y,p;
     32     friend bool operator <(const stone &A,const stone &B) {
     33         return A.y<B.y;
     34     }
     35     stone(int y,int p):y(y),p(p){}
     36 };
     37 vector<stone>vc[N];
     38 
     39 struct node {
     40     int i,p;
     41     node(int i,int p):i(i),p(p){}
     42 };
     43 vector<node>v2[N];
     44 
     45 struct sgtree { 
     46     LL sg[N<<2],lz[N<<2];
     47     #define lc (x<<1)
     48     #define rc ((x<<1)|1)
     49     #define mid ((l+r)>>1)
     50     void down(int x,int l,int r) {
     51         if(lz[x]==1) return;
     52         sg[lc]=sg[lc]*lz[x]%mod; lz[lc]=lz[lc]*lz[x]%mod;
     53         sg[rc]=sg[rc]*lz[x]%mod; lz[rc]=lz[rc]*lz[x]%mod;
     54         lz[x]=1;
     55     }
     56     
     57     void build(int x,int l,int r) {
     58         lz[x]=1;
     59         if(l==r) { sg[x]=1LL; return; }
     60         build(lc,l,mid); build(rc,mid+1,r);
     61         sg[x]=(sg[lc]+sg[rc])%mod;
     62     }
     63     
     64     void upd(int x,int l,int r,int ql,int qr,LL v) {
     65         if(l>=ql&&r<=qr) {
     66             sg[x]=sg[x]*v%mod; lz[x]=lz[x]*v%mod; return;
     67         }
     68         down(x,l,r);
     69         if(ql<=mid) upd(lc,l,mid,ql,qr,v);
     70         if(qr>mid) upd(rc,mid+1,r,ql,qr,v);
     71         sg[x]=(sg[lc]+sg[rc])%mod;
     72     }
     73 }T;
     74 
     75 int opl[N],opr[N],qql[N],qqr[N];
     76 
     77 #define ANS
     78 int main() {
     79 #ifdef ANS
     80     freopen("max.in","r",stdin);
     81     freopen("max.out","w",stdout);
     82 #endif
     83     read(n); read(m); read(q);
     84     For(i,1,m) {
     85         int x,y,p;
     86         read(x); read(y); read(p);
     87         vc[x].push_back(stone(y,p));
     88         ls[++ls[0]]=y;
     89     }
     90     int nl=1,nowp=1;
     91     For(i,1,q) {
     92         read(qql[i]); read(qqr[i]);
     93         while(qql[i]>nowp) {
     94             while(nl<i&&qqr[nl]<nowp) nl++;
     95             opl[nowp]=nl; opr[nowp]=i-1;
     96             nowp++;
     97         }
     98         while(nl<i&&qqr[nl]<nowp) nl++;
     99         opl[nowp]=nl; opr[nowp]=i;
    100     }
    101     while(nowp<=n) {
    102         while(nl<=q&&qqr[nl]<nowp) nl++;
    103         opl[nowp]=nl; opr[nowp]=q; nowp++;
    104     }
    105     
    106     sort(ls+1,ls+ls[0]+1);
    107     sz=unique(ls+1,ls+ls[0]+1)-(ls+1);
    108     For(i,1,n) sort(vc[i].begin(),vc[i].end());
    109     For(i,1,n) {
    110         int up=vc[i].size();
    111         LL pr=1,tp=1;
    112         For(j,0,up-1) tp=(1LL-vc[i][j].p+mod)%mod*tp%mod;
    113         For(j,0,up-1) {
    114             LL px=(pr-tp+mod)%mod;
    115             pr=(1LL-vc[i][j].p+mod)%mod*pr%mod;
    116             int y=lower_bound(ls+1,ls+sz+1,vc[i][j].y)-ls;
    117             v2[y].push_back(node(i,px));
    118         }
    119     }
    120     
    121     For(i,1,n) now[i]=1;
    122     T.build(1,1,q);
    123     ls[0]=0;
    124     Rep(x,sz,1) {
    125         LL tpp=(ls[x]%mod-ls[x-1]%mod+mod)%mod;
    126         int up=v2[x].size();
    127         For(i,0,up-1) {
    128             int pos=v2[x][i].i,tp=(1LL-v2[x][i].p+mod)%mod;
    129             if(now[pos]==0) continue;
    130             if(opl[pos]&&opl[pos]<=opr[pos]) {
    131                 T.upd(1,1,q,opl[pos],opr[pos],tp*ksm(now[pos],mod-2)%mod);
    132                 now[pos]=tp;
    133             }
    134         }
    135         ans=(ans+(q-T.sg[1]+mod)%mod*tpp%mod)%mod;
    136     }
    137     printf("%lld
    ",ans);
    138     Formylove;
    139 }
    View Code
  • 相关阅读:
    HDU 3833 YY's new problem ()
    从文件读入16进制数转化为10进制数再输出到文件中
    UESTC 1215 (思维题 旋转)
    HDU2067卡特兰数
    HDU2050离散数学折线分割平面
    cshell学习
    C++学习1
    QT学习1
    QT Creator常用快捷键
    Ubuntu14.04安装QT5.5
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9831782.html
Copyright © 2020-2023  润新知