zoukankan      html  css  js  c++  java
  • [考试反思]0314省选模拟45:偏离

    又一次把重点放错了题。$T2$没想出的情况下没怎么弄$T3$然而实际上$T3$的部分分最肥。

    然后总分就崩了。$T2$写了个神奇的莫队,然而出题人并没有想到这个然后没有留分,结果比暴力还惨。

    $T1$倒是比期望高了一点。但是也差不多吧。

    以为还是一如既往的过百即稳。。。然而其实只是题简单。

    我感觉我像个弱智,$T2$都想到离线了为啥先想到的是莫队???

    脑子里的乱搞思想太多,反而掩盖了正解。。。

    要相信自己能想出来啊,还有抢救的机会啊啊啊

    T1:mxtrix

    大意:求所有子矩阵的权值和。定义为本质不同的行数。$nm le 5 imes 10^5$

    所以其实我们只在意每个串作为多少个矩阵的这种串的第一次出现。

    大概是个扫描线?左端点不断向右移动然后考虑增量的变化。

    最开始就相当与对于建一个$trie$然后在每个节点上维护在哪些串里出现过,每次插入时产生影响的就是前驱后继。

    然后考虑左端点右移会发生什么,就是把$trie$的根扔掉然后所有儿子合并起来当新的根。

    启发式就行了。$O(nm log^2n)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 1111111
     4 int n,m,rt,pc,v[S];long long ans,rate;
     5 set<int>s[S];unordered_map<int,int>M[S];
     6 int read(){char ch=getchar();int p=0;while(!isdigit(ch))ch=getchar();while(isdigit(ch))p=p*10+ch-48,ch=getchar();return p;}
     7 void ins(int p,int w){
     8     if(s[p].find(w)!=s[p].end())return;
     9     auto i=s[p].lower_bound(w);int x=*(--i); i++; s[p].insert(w); rate+=(w-x)*(n-w+1ll);
    10     if(i!=s[p].end())rate-=(w-x)*(n-(*i)+1ll);
    11 }
    12 void insert(int&p,int o,int l){
    13     if(!p)p=++pc,s[pc].insert(0); ins(p,o);
    14     if(l)insert(M[p][read()],o,l-1);
    15 }
    16 void delctb(int p,int lst=0){for(auto x:s[p])rate-=(x-lst)*(n-x+1ll),lst=x;}
    17 void merge(int&p1,int p2){
    18     if(!p1){p1=p2;return;}
    19     if(s[p2].size()>s[p1].size())swap(s[p1],s[p2]);
    20     delctb(p2); for(auto x:s[p2])ins(p1,x); s[p2].clear();
    21     for(auto x:M[p2])merge(M[p1][x.first],x.second); M[p2].clear();
    22 }
    23 void delrt(){
    24     int c=0;delctb(rt);s[rt].clear();
    25     ans+=rate; int R=rt;
    26     if(m)for(auto x:M[R])if(!c)rt=x.second,c=1;else merge(rt,x.second); M[R].clear();
    27 }
    28 int main(){cin>>n>>m;for(int i=1;i<=n;++i)insert(rt,i,m);while(m--)delrt();cout<<ans;}
    View Code

    T2:sequence

    大意:序列,多次询问子串$[l,r]$有多少子串满足区间按位与是$k$的倍数。$n le 10^5,q le 5 imes 10^5$

    离线,扫描线。

    后缀按位与每次只会变化$log$次,所以往前跳同时线段树区间加就行。

    复杂度$O(nlog^n+qlogn)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define S 100005
     4 int n,qn,k,a[S],Lst[30][S],q[33];long long v[S<<2],Ans[5*S],lz[S<<2];
     5 struct Q{int l,r,o;}qs[S*5];
     6 #define lc p<<1
     7 #define rc lc|1
     8 #define md (cl+cr>>1)
     9 void add(int l,int r,int p=1,int cl=1,int cr=n){
    10     if(l<=cl&&cr<=r){v[p]+=cr-cl+1;lz[p]++;return;}
    11     if(l<=md)add(l,r,lc,cl,md);if(r>md)add(l,r,rc,md+1,cr);
    12     v[p]=v[lc]+v[rc];
    13 }
    14 long long ask(int l,int r,int p=1,int cl=1,int cr=n){
    15     if(l<=cl&&cr<=r)return v[p];
    16     if(lz[p])lz[lc]+=lz[p],lz[rc]+=lz[p],v[lc]+=(md-cl+1)*lz[p],v[rc]+=(cr-md)*lz[p],lz[p]=0;
    17     return (l<=md?ask(l,r,lc,cl,md):0)+(r>md?ask(l,r,rc,md+1,cr):0);
    18 }
    19 int main(){
    20     cin>>n>>qn>>k;
    21     for(int i=1;i<=n;++i)scanf("%d",&a[i]); 
    22     for(int i=1;i<=qn;++i)scanf("%d%d",&qs[i].l,&qs[i].r),qs[i].o=i;
    23     sort(qs+1,qs+1+qn,[](Q x,Q y){return x.r<y.r;});
    24     for(int i=1;i<=n;++i)for(int j=0;j<30;++j)Lst[j][i]=a[i]&1<<j?Lst[j][i-1]:i;
    25     for(int i=1,pt=1;i<=n;++i){
    26         int c=0,lp=i,num=a[i];
    27         for(int x=0;x<30;++x)if(num&1<<x)q[++c]=Lst[x][i];
    28         sort(q+1,q+1+c);
    29         for(int x=c;~x;--x)if(lp!=q[x]){
    30             if(num%k==0)add(q[x]+1,lp);
    31             num&=a[q[x]];lp=q[x];
    32         }
    33         while(qs[pt].r==i)Ans[qs[pt].o]=ask(qs[pt].l,i),pt++;
    34     }
    35     for(int i=1;i<=qn;++i)printf("%lld
    ",Ans[i]);
    36 }
    View Code

    T3:permutation

    大意:从左往右满足是出现过的最大值的有$a$个,从右往左有$b$个,长度为$n$的排列数。$n le 2 imes 10^5$

    抽象题意,发现就是指定最大值的位置后,左边划分为$a-1$个环,右边$b-1$个。

    环之间顺序固定(换内最大值由小到大),环的断开点确定(最大值靠近全局最大值)。

    然后组合含义出发,除$n-1$外所有数分成$a+b-2$个环,再选出$a-1$个放在左边。

    所以只需要预处理斯特林数,一行就行。用到的是那个$prodlimits_{i=0}^{n-1} (x+i)=sumlimits_{i=0}^{n} x^i S(n,i)$

    然后老套路分治一边求另一边就行了。时间复杂度$O(nlogn)$。毒瘤出题人喜闻乐见卡常卡掉$std$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 998244353
     4 #define S 1<<20
     5 int fac[S],inv[S],len,rev[S],a[S],b[S],r[S],pw[S];
     6 int qp(int b,int t,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
     7 void setlen(int n){
     8     len=1;while(len<=n)len<<=1;
     9     for(int i=1;i<len;++i)rev[i]=rev[i>>1]>>1|(i&1?len>>1:0);
    10 }
    11 void NTT(int*a,int op=1){
    12     for(int i=1;i<len;++i)if(rev[i]>i)swap(a[rev[i]],a[i]);
    13     for(int i=1;i<len;i<<=1)for(int j=0,w=qp(3,(mod-1)/2/i*op+mod-1);j<len;j+=i<<1)
    14         for(int k=j,t=1,x,y;k<i+j;++k,t=1ll*t*w%mod)
    15             x=a[k],y=1ll*a[k+i]*t%mod,a[k]=(x+y)%mod,a[k+i]=(x-y+mod)%mod;
    16     if(op<0)for(int i=0,iv=qp(len,mod-2);i<len;++i)a[i]=1ll*a[i]*iv%mod;
    17 }
    18 void solve(int n){
    19     if(!n){a[0]=1;return;}
    20     int L=n>>1; solve(L); setlen(n);
    21     for(int i=0;i<len;++i)r[i]=b[i]=0;
    22     pw[0]=1;
    23     for(int i=1;i<=L;++i)pw[i]=pw[i-1]*1ll*L%mod;
    24     for(int i=0;i<=L;++i)r[i]=a[i]*1ll*fac[i]%mod;
    25     for(int i=0;i<=L;++i)b[L-i]=pw[i]*1ll*inv[i]%mod;
    26     NTT(r);NTT(b); for(int i=0;i<len;++i)b[i]=1ll*b[i]*r[i]%mod; NTT(b,-1);
    27     for(int i=0;i<=L;++i)b[i]=b[i+L]*1ll*inv[i]%mod;
    28     for(int i=L+1;i<len;++i)b[i]=0;
    29     NTT(a);NTT(b); for(int i=0;i<len;++i)a[i]=1ll*a[i]*b[i]%mod; NTT(a,-1);
    30     if(n&1){
    31         for(int i=n;i;--i)a[i]=((n-1ll)*a[i]+a[i-1])%mod;
    32         a[0]=a[0]*(n-1ll)%mod;
    33     }
    34 }
    35 int main(){
    36     int n,A,B;
    37     cin>>n>>A>>B;
    38     for(int i=fac[0]=1;i<=n;++i)fac[i]=fac[i-1]*1ll*i%mod;
    39     inv[n]=qp(fac[n],mod-2);
    40     for(int i=n-1;~i;--i)inv[i]=inv[i+1]*(i+1ll)%mod;
    41     solve(n-1);
    42     printf("%lld
    ",1ll*a[A+B-2]*fac[A+B-2]%mod*inv[A-1]%mod*inv[B-1]%mod);
    43 }
    View Code
  • 相关阅读:
    ImageWatch 无法安装在VS2017环境下的解决方案
    Android CmakeList
    Android 工程越来越大,运行变卡解决方法
    奥卡姆剃刀(简约之法则)
    Cmake时 如何在windows命令行 选择vs版本
    ubuntu 18.04 安装tensorflow 2 cuda10 CUDNN Anaconda3
    Centos7简易通过yum安装phpmyadmin
    centos7 nigx 免费永久获取 Let‘s Encrypt 证书
    Execution failed for task ':app:compileDebugJavaWithJavac'
    centos 安装aconda
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12494777.html
Copyright © 2011-2022 走看看