noi2017 day1 题解
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 题解的更多相关文章
- THUSC2017 Day1题解
THUSC2017 Day1题解 巧克力 题目描述 "人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道." 明明收到了一大块巧克力,里面有若干小块,排成n行m列.每一小块都有 ...
- BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...
- 【NOIP2014】Day1题解+代码
Day1 T1 签到题,模拟一下随便写就能过. 不过小心像我一样表打错傻逼的调了10min. #include <algorithm> #include <iostream> ...
- ZJOI2019 Day1 题解
想要继续向前,就从克服内心的恐惧开始. 麻将 题意 在麻将中,我们称点数连续的三张牌或三张点数一样的成为面子,称两张点数一样的牌为对子.一副十四张麻将牌的胡牌条件是可以分成四个面子和一个对子或者分成七 ...
- Noip 2016 Day1 题解
老师让我们刷历年真题, 然后漫不经心的说了一句:“你们就先做做noip2016 day1 吧” ...... 我还能说什么,,,,,老师你这是明摆着伤害我们啊2333333333 预计分数:100+2 ...
- NOI 2016 Day1 题解
今天写了NOI2016Day1的题,来写一发题解. T2 网格 题目传送门 Description \(T\) 次询问,每次给出一个 \(n\times m\) 的传送门,上面有 \(c\) 个位置是 ...
- 十连测Day1 题解
A. 奥义商店 有一个商店,n个物品,每个物品有一个价格和一种颜色. 有m个操作,操作有两种,一种是修改一个位置的价格,另一种是购买,每次购买指定一个公差d和一个位置k,找到包含这个位置k公差为d的同 ...
- 【NOIP2013】DAY1题解+代码
T1 傻逼快速幂,敲敲就过了. 我跟你们讲个笑话当时我以为这个数据范围过不了于是想出了求GCD再推规律什么的magic方法中途还咨询了某个学长. 然后怎么想都是不可做. ……直到我发现我昨年的代码一个 ...
- NOIP 2018 day1 题解
今年noip的题和去年绝对是比较坑的题了,但是打好的话就算是普通水准也能350分以上吧. t1: 很显然这是一个简单的dp即可. #include<iostream> #include&l ...
随机推荐
- 软工作业No.8 第六周 Alpha阶段项目复审
小组的名字和链接 优点 缺点,bug报告 (至少140字) 最终名次 (无并列) 未来的将来的明天在那里等你 http://www.cnblogs.com/macrae/p/9940387.html ...
- IoC基础例子
一个简单的例子: 一般新建一个com.dao包,存放一些dao接口. com.dao.impl里面存放具体的dao com.service存放service接口 com.service.impl具体的 ...
- 关于Behold the Kickmen (球员登场)
音乐:『Boring,Boring——』作者浑厚的男中音响起,伴随着劲爆的动感音乐 非同正式却又无伤大雅的规则:足球场是圆形的,而且四周有反弹围墙 加强操作的一些设定: 踢踢人射门蓄力时,时间会静止, ...
- Vue2.0 分页插件pagination使用详细说明
Vue2.0 分页pagination使用 插件下载地址:Vue_Pagination 插件描述:基于jQuery的分页插件大家都用过很多了吧,今天分享一下基于Vue的分页插件pagination.j ...
- 学习magento要学哪些知识
php框架水平,具体点的就是大名鼎鼎的ZF框架.别急,先还是熟悉下OSC吧,主要是热身下商城的那些业务流的知识,基本的数据流程.自己做模板的话CSS2.0水平还不能太低.JS框架JQ吧相对简单点.当然 ...
- CSS的使用
1.行内样式/内联样式 特点:在具体的HTML标签中引入CSS代码 语法:所有的HTML标签都具有一个style属性,属性值就可以使用CSS样式规则 <标签 style="CSS样式规 ...
- 51Nod 1069:Nim游戏(尼姆博弈)
1069 Nim游戏 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 有N堆石子.A B两个人轮流拿,A先拿.每次只能从一堆中取若干个,可将一堆全取走, ...
- CTF-练习平台-Misc之 多种方法解决
五.多种方法解决 题目提示:在做题过程中你会得到一个二维码图片 下载文件后解压发现是一个exe文件,打开后报错:将文件后缀名改为txt打开后发现是base64编码 联系到提示说最后是一个二维码,将它转 ...
- Python类之魔术方法
一.什么是魔术方法? 在Python的方法,我们经常会遇见__XXX__(),这样的方法,我们一般称为"魔术方法",赶紧搬个小板凳,我们一起来看看魔术方法有啥神奇的地方,这些方法又 ...
- LG2044 [NOI2012]随机数生成器
题意 栋栋最近迷上了随机算法,而随机数是生成随机算法的基础.栋栋准备使用线性同余法(Linear Congruential Method)来生成一个随机数列,这种方法需要设置四个非负整数参数m,a,c ...