d1t1

sol1:用线段树维护区间是否全0/全1,叶子上压位维护对应位置的数位,加法首先对叶子加,如需进位则向右找到第一个不是全1的叶子+1,中间部分全1部分打上反转标记,减法同理。

#include<cstdio>
int _(){
int x=,f=,c=getchar();
while(c<)c=='-'?f=-:,c=getchar();
while(c>)x=x*+c-,c=getchar();
return x*f;
}
const int N=;
typedef unsigned int u32;
int n,_l,flag;
u32 _ans;
int mx;
struct node{
node*lc,*rc;
int rev;
u32 _or,_and;
void revs(){
rev^=;
_or=~_or;
_and=~_and;
}
void up(){
_or=lc->_or|rc->_or;
_and=lc->_and&rc->_and;
}
void dn(){
if(rev){
rev^=;
lc->revs();
rc->revs();
}
}
void find(int L,int R){
if(L==R){
_ans=_or;
return;
}
int M=(L+R)>>;
dn();
if(_l<=M)lc->find(L,M);
else rc->find(M+,R);
}
void inc(int L,int R){
if(L==R){
flag=(_and+_ans<_and);
_and+=_ans;
_or=_and;
return;
}
int M=(L+R)>>;
dn();
if(_l<=M)lc->inc(L,M);
else rc->inc(M+,R);
up();
}
void dec(int L,int R){
if(L==R){
flag=(_and-_ans>_and);
_and-=_ans;
_or=_and;
return;
}
int M=(L+R)>>;
dn();
if(_l<=M)lc->dec(L,M);
else rc->dec(M+,R);
up();
}
void inc1(int L,int R){
if(flag)return;
if(_l<=L){
if(_and==~0u)return revs();
if(L==R){
_or=++_and;
flag=;
return;
}
}
dn();
int M=(L+R)>>;
if(_l<=M)lc->inc1(L,M);
rc->inc1(M+,R);
up();
}
void dec1(int L,int R){
if(flag)return;
if(_l<=L){
if(_or==0u)return revs();
if(L==R){
_or=--_and;
flag=;
return;
}
}
dn();
int M=(L+R)>>;
if(_l<=M)lc->dec1(L,M);
rc->dec1(M+,R);
up();
}
}ns[N*],*np=ns,*rt;
node*build(int L,int R){
node*w=np++;
if(L<R){
int M=(L+R)>>;
w->lc=build(L,M);
w->rc=build(M+,R);
}
w->_or=w->_and=w->rev=;
return w;
}
void inc(u32 a,int x){
if(!a)return;
_ans=a;_l=x;
rt->inc(,mx);
if(flag){
flag=;
_l=x+;
rt->inc1(,mx);
}
}
void dec(u32 a,int x){
if(!a)return;
_ans=a;_l=x;
rt->dec(,mx);
if(flag){
flag=;
_l=x+;
rt->dec1(,mx);
}
}
int main(){
n=_();_();_();_();
mx=n+;
if(mx<)mx=;
rt=build(,mx);
for(int i=;i<n;++i){
if(_()==){
int a0=_(),b=_();
int b1=b>>,b2=b&;
if(a0>){
u32 a=a0;
inc(a<<b2,b1);
if(b2)inc(a>>(-b2),b1+);
}else if(a0<){
u32 a=-a0;
dec(a<<b2,b1);
if(b2)dec(a>>(-b2),b1+);
}
}else{
int k=_();
_l=k>>;
rt->find(,mx);
printf("%d\n",_ans>>(k&)&);
}
}
return ;
}

sol2:用两个高精度数分别记录加法和减法的贡献,用线段树维护这两个数不同的数位,查询某一位时考虑两数当前位以及两数低位的大小关系可以得出答案。

#include<cstdio>
int _(){
int x;
scanf("%d",&x);
return x;
}
const int N=<<|,mx=<<;
int n;
bool v1[N],v2[N],tr[N*];
int l,r;
void add(bool*v,int x){
for(;v[x];v[x++]=);
v[x]=;
if(x>r)r=x;
}
int pre(int x){
for(x+=mx;x;x>>=)if(x&&tr[x^]){
for(x^=;x<mx;x=x<<^tr[x<<^]);
return x-mx;
}
return -;
}
int main(){
n=_();_();_();_();
for(int i=;i<n;++i){
if(_()==){
int a=_(),b=_();
if(!a)continue;
l=r=b;
if(a>){
for(int i=;i<=;++i)if(a>>i&)add(v1,b+i);
}else{
a=-a;
for(int i=;i<=;++i)if(a>>i&)add(v2,b+i);
}
for(int i=l;i<=r;++i)tr[i+mx]=v1[i]^v2[i];
for(l=(l+mx)>>,r=(r+mx)>>;l;l>>=,r>>=){
for(int i=l;i<=r;++i)tr[i]=tr[i<<]|tr[i<<^];
}
}else{
int x=_(),p=pre(x);
puts(tr[x+mx]^(p!=-&&v1[p]<v2[p])?"":"");
}
}
return ;
}

d1t2

预处理询问涉及的串的hash值,用散列表离散化,对每次修改操作,枚举新产生/消失的长度<=50的子串,若其hash值等于某个询问,则对应在散列表上记录贡献。

#include<cstdio>
#include<cstring>
#include<vector>
typedef unsigned long long u64;
const int P=,N=,Q=,pz=,H=<<;
int _(){
int x=,f=,c=getchar();
while(c<)c=='-'?f=-:,c=getchar();
while(c>)x=x*+c-,c=getchar();
return x*f;
}
int n,m,mk=;
int v[N],nx[N],pv[N];
char ss[];
u64 h1[],pp[];
int qs[Q][];
std::vector<int>qv[Q];
u64 hx[H+];
int hy[H+];
int ins(u64 x){
int w=(x^x>>^x>>)&(H-);
while(hx[w]){
if(hx[w]==x)return w;
w=(w+)&(H-);
}
hx[w]=x;
return w;
}
bool inc(u64 x,int a){
int w=(x^x>>^x>>)&(H-);
while(hx[w]){
if(hx[w]==x){
hy[w]+=a;
return ;
}
w=(w+)&(H-);
}
return ;
}
int ls[],lp,t0[];
int ms[],mp=;
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
void chk(int a,int b,int c){
lp=mp=;
for(int i=,w=a;i<mk&&w;++i,w=pv[w])ls[lp++]=v[w];
for(int i=lp-;i>=;--i)ms[++mp]=ls[i];
for(int i=,w=b;i<mk&&w;++i,w=nx[w])ms[++mp]=v[w];
for(int i=;i<=mp;++i)h1[i]=h1[i-]*pz+ms[i];
for(int i=;i<lp;++i){
int r=min(mp,i+mk);
for(int j=lp+;j<=r;++j){
inc(h1[j]-h1[i]*pp[j-i],c);
}
}
}
int main(){
n=_();m=_();
pp[]=;
for(int i=;i<=;++i)pp[i]=pp[i-]*pz;
for(int i=;i<=n;++i)++t0[v[i]=_()];
for(int i=;i<=m;++i){
qs[i][]=_();
if(qs[i][]==){
qs[i][]=_();
qs[i][]=_();
}else if(qs[i][]==){
qs[i][]=_();
}else{
scanf("%s",ss+);
int len=strlen(ss+);
int k=_();
if(k>mk)mk=k;
for(int j=;j<=len;++j)h1[j]=h1[j-]*pz+ss[j]-'';
qv[i].resize(max(len-k+,));
for(int j=k;j<=len;++j){
qv[i][j-k]=ins(h1[j]-h1[j-k]*pp[k]);
}
}
}
for(int i=;i<=;++i)inc(i,t0[i]);
for(int i=;i<=m;++i){
if(qs[i][]==){
int a=qs[i][],b=qs[i][];
nx[a]=b;pv[b]=a;
chk(a,b,);
}else if(qs[i][]==){
int a=qs[i][],b=nx[a];
nx[a]=pv[b]=;
chk(a,b,-);
}else if(qs[i][]==){
int ans=;
for(int j=;j<qv[i].size()&&ans;++j){
ans=u64(ans)*hy[qv[i][j]]%P;
}
printf("%d\n",ans);
}
}
return ;
}

d1t3

询问=k拆成<=k和<=k-1

只需考虑原矩形每一列最下面的一个可选位置,令f[x][y]表示最下方x行可选,第x+1行存在不可选位置,宽度y的矩形 合法的概率,则

$f[x][y]=\sum_{i=0}^{y-1}f[>=x][i]f[>x][y-1-i]$

这里dp不处理x=0的部分,只考虑x>0,因此0<xy<=k,暴力转移的时间复杂度可以接受

把0的影响表示为一个常系数线性齐次递推的形式,转化为多项式幂取模计算

#include<cstdio>
#include<cstring>
const int P=;
typedef long long i64;
const i64 X=(1ll<<)/P*P;
int pw(int a,int n){
int v=;
for(;n;n>>=,a=i64(a)*a%P)if(n&)v=i64(v)*a%P;
return v;
}
int n,m,q,A,B;
int f[][],g[][],cs[],v[],f0[],a0[],a1[];
i64 c[];
void mul(int*a,int*b,int m){
memset(c,,sizeof(c));
for(int i=;i<=m;++i){
for(int j=;j<=m;++j)c[i+j]+=i64(a[i])*b[j];
if(i%==||i==m)for(int j=;j<=m+i;++j)c[j]-=(c[j]>>)*X;
}
for(int i=m*;i>m;--i){
c[i]%=P;
for(int j=;j<=m+;++j)c[i-j]+=c[i]*v[j];
if((m*-i)%==)for(int j=;j<i;++j)c[j]-=(c[j]>>)*X;
}
for(int i=;i<=m;++i)a[i]=c[i]%P;
}
int cal(int n,int m,int q){
if(!m)return pw(-q,n);
memset(f,,sizeof(f));
memset(g,,sizeof(g));
g[m+][]=;
cs[]=-q;
for(int i=;i<=m;++i)cs[i]=cs[i-]*i64(q)%P;
for(int i=m;i;--i){
memcpy(g[i],g[i+],sizeof(g[]));
for(int j=;j<=m/i;++j){
for(int k=;k<j;++k){
f[i][j]=(f[i][j]+i64(g[i][k])*g[i+][j--k])%P;
}
f[i][j]=i64(cs[i])*f[i][j]%P;
g[i][j]=(f[i][j]+g[i][j])%P;
}
}
for(int i=;i<=m+;++i)v[i]=g[][i-]*i64(cs[])%P;
f0[]=pw(cs[],P-);
for(int i=;i<=m+;++i){
f0[i]=;
for(int j=;j<=i;++j)f0[i]=(f0[i]+f0[i-j]*i64(v[j]))%P;
}
memset(a0,,sizeof(a0));
memset(a1,,sizeof(a1));
a0[]=a1[]=;
for(;n;n>>=,mul(a1,a1,m))if(n&)mul(a0,a1,m);
int s=;
for(int i=;i<=m;++i)s=(s+i64(a0[i])*f0[i])%P;
return s;
}
int main(){
scanf("%d%d%d%d",&n,&m,&A,&B);
++n;
q=i64(A)*pw(B,P-)%P;
int s=(cal(n,m,q)-cal(n,m-,q))%P;
printf("%d\n",(s+P)%P);
return ;
}

noi2017 day1 题解的更多相关文章

  1. THUSC2017 Day1题解

    THUSC2017 Day1题解 巧克力 题目描述 "人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道." 明明收到了一大块巧克力,里面有若干小块,排成n行m列.每一小块都有 ...

  2. BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...

  3. 【NOIP2014】Day1题解+代码

    Day1 T1 签到题,模拟一下随便写就能过. 不过小心像我一样表打错傻逼的调了10min. #include <algorithm> #include <iostream> ...

  4. ZJOI2019 Day1 题解

    想要继续向前,就从克服内心的恐惧开始. 麻将 题意 在麻将中,我们称点数连续的三张牌或三张点数一样的成为面子,称两张点数一样的牌为对子.一副十四张麻将牌的胡牌条件是可以分成四个面子和一个对子或者分成七 ...

  5. Noip 2016 Day1 题解

    老师让我们刷历年真题, 然后漫不经心的说了一句:“你们就先做做noip2016 day1 吧” ...... 我还能说什么,,,,,老师你这是明摆着伤害我们啊2333333333 预计分数:100+2 ...

  6. NOI 2016 Day1 题解

    今天写了NOI2016Day1的题,来写一发题解. T2 网格 题目传送门 Description \(T\) 次询问,每次给出一个 \(n\times m\) 的传送门,上面有 \(c\) 个位置是 ...

  7. 十连测Day1 题解

    A. 奥义商店 有一个商店,n个物品,每个物品有一个价格和一种颜色. 有m个操作,操作有两种,一种是修改一个位置的价格,另一种是购买,每次购买指定一个公差d和一个位置k,找到包含这个位置k公差为d的同 ...

  8. 【NOIP2013】DAY1题解+代码

    T1 傻逼快速幂,敲敲就过了. 我跟你们讲个笑话当时我以为这个数据范围过不了于是想出了求GCD再推规律什么的magic方法中途还咨询了某个学长. 然后怎么想都是不可做. ……直到我发现我昨年的代码一个 ...

  9. NOIP 2018 day1 题解

    今年noip的题和去年绝对是比较坑的题了,但是打好的话就算是普通水准也能350分以上吧. t1: 很显然这是一个简单的dp即可. #include<iostream> #include&l ...

随机推荐

  1. 取TTable 过滤后的记录数

    http://bbs.csdn.net/topics/100057274 可以用AstaClientDataSet这个控件,有filterCount这个属性.另外你还可看它的源码,就能写出filter ...

  2. OPENWRT常用设置

    常用设置: 计划任务,定时重启 系统--计划任务,每行一个计划任务. 然后是计划任务列表的格式: [minute] [hour] [day of month] [month] [day of week ...

  3. (C/C++学习笔记) 十四. 动态分配

    十四. 动态分配 ● C语言实现动态数组 C语言实现动态数组,克服静态数组大小固定的缺陷 C语言中,数组长度必须在创建数组时指定,并且只能是一个常数,不能是变量.一旦定义了一个数组,系统将为它分配一个 ...

  4. DevExpress v17.2新版亮点—WPF篇(七)

    用户界面套包DevExpress v17.2终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress WPF v17.2 新的Hamburger Menu.Sched ...

  5. centos7 vsftp的安装

    首先下载vsftp yum install -y vsftpd 安装好了之后 编辑默认的文件 vi /etc/vsftpd/vsftpd.conf 更改下面的: anonymous_enable=NO ...

  6. TV-B-Gone Kit - Universal v1.2

  7. 在C#中如何定义一个变长的结构数组?如果定义好了,如何获得当前数组的长度?

    用ArrayList,他就相当于动态数组,用add方法添加元素,remove删除元素,count计算长度

  8. Python 名称空间和作用域

    a = 10 # lst = [1,2,3,4] # # # 内置函数 print("你好啊,我叫赛利亚") # def chi(): a = 10 b = 20 # # # # ...

  9. SWIFT中切換UIContainerView內的Controller

    如下,一个UIContainerView内切换两个Controller,当点击登录的时候UIContainerView的视图为LoginController,当点击登记的时候UIContainerVi ...

  10. NBUT 1218 You are my brother 2010辽宁省赛

    Time limit 1000 ms Memory limit 131072 kB Little A gets to know a new friend, Little B, recently. On ...