NOIP模拟测试11
这次考试T1想到了正解没有去实现,然后就死了,不过我估计就算想到正解也会挂(26^2和暴力一个分),肝了两个小时T2屁都没蹦出来,T3没有搞清那个式子的含义。
(不过一分没挂)
T1:string
开26棵线段树维护,还有一种更快的方法:对于每个树上的节点,只有左右儿子字符相同时才更新,不然不更新,这种打法将26换成了较小的常数,并且不需要memset,真是出家旅行必备骗分之良器
#include <bits/stdc++.h> typedef long long LL; inline int rd() {
int a = , b = ; char c = getchar();
while (!isdigit(c)) a = c == '-' ? : , c = getchar();
while (isdigit(c)) b = b * + c - '', c = getchar();
return a ? b : -b;
} const int N = + ; int n, m; char str[N]; int same[N * ]; #define ls(p) p << 1
#define rs(p) p << 1 | 1 void pushup(int p) {
if (same[ls(p)] == same[rs(p)])
same[p] = same[ls(p)];
else same[p] = ;
} void pushdown(int p) {
if (same[p])
same[ls(p)] = same[rs(p)] = same[p];
} void build(int p, int L, int R) {
if (L == R) return (void)(same[p] = str[L]);
int mid = (L + R) >> ;
build(ls(p), L, mid);
build(rs(p), mid + , R);
pushup(p);
} void change(int p, int l, int r, int v, int L, int R) {
if (l <= L && r >= R) return (void)(same[p] = v);
pushdown(p); int mid = (L + R) >> ;
if (l <= mid) change(ls(p), l, r, v, L, mid);
if (r > mid) change(rs(p), l, r, v, mid + , R);
pushup(p);
} int que[]; void query(int p, int l, int r, int L, int R) {
if (l <= L && r >= R && same[p])
return (void)(que[same[p]] += (R - L + ));
pushdown(p); int mid = (L + R) >> ;
if (l <= mid) query(ls(p), l, r, L, mid);
if (r > mid) query(rs(p), l, r, mid + , R);
} void write(int p, int L, int R) {
if (L == R) return (void)(putchar(same[p]));
pushdown(p); int mid = (L + R) >> ;
write(ls(p), L, mid);
write(rs(p), mid + , R);
} int main() {
scanf("%d%d%s", &n, &m, str + );
build(, , n);
while (m--) {
int l, r, x; scanf("%d%d%d", &l, &r, &x);
for (int i = 'a'; i <= 'z'; ++i) que[i] = ;
query(, l, r, , n);
if (x == ) {
for (int i = 'a', lst = l; i <= 'z'; ++i) if (que[i])
change(, lst, lst + que[i] - , i, , n), lst = lst + que[i];
} else {
for (int i = 'z', lst = l; i >= 'a'; --i) if (que[i])
change(, lst, lst + que[i] - , i, , n), lst = lst + que[i];
}
}
write(, , n);
return ;
}
Orz
#include<iostream>
#include<cstdio>
#include<cstring>
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
const int MAXN=;
int N,M;
char s[MAXN];
int t[];
char wd[MAXN*];
int cnt[MAXN*][],tg[MAXN];
bool fg[MAXN*];
void bt(int p,int l,int r){
tg[p]=-;
if(l==r){
wd[p]=s[l];
cnt[p][s[l]-'a']=;
return;
}
int mid=(l+r)>>;
bt(p<<,l,mid);
bt(p<<|,mid+,r);
int fgg=;
for(int i=;i<;++i){
cnt[p][i]=cnt[p<<][i]+cnt[p<<|][i];
fgg+=(cnt[p][i]!=);
}
fg[p]=(fgg==);
}
void get(int p,int l,int r,int ll,int rr,int out[]){
if(ll<=l && r<=rr){
for(int i=;i<;++i)
out[i]+=cnt[p][i];
return;
}
if(tg[p]!=-){
int id=tg[p];
int mid=(l+r)>>;
clr(cnt[p<<]);
clr(cnt[p<<|]);
cnt[p<<][id]=mid-l+;
cnt[p<<|][id]=r-(mid+)+;
tg[p<<]=tg[p<<|]=id;
wd[p<<]=wd[p<<|]=id+'a';
fg[p<<]=fg[p<<|]=;
tg[p]=-;
}
int mid=(l+r)>>;
if(ll<=mid)
get(p<<,l,mid,ll,rr,out);
if(rr>mid)
get(p<<|,mid+,r,ll,rr,out);
}
void cover(int p,int l,int r,int ll,int rr,int id){
if(ll<=l && r<=rr){
clr(cnt[p]);
cnt[p][id]=r-l+;
tg[p]=id;
wd[p]=id+'a';
fg[p]=;
return;
}
if(tg[p]!=-){
int id=tg[p];
int mid=(l+r)>>;
clr(cnt[p<<]);
clr(cnt[p<<|]);
cnt[p<<][id]=mid-l+;
cnt[p<<|][id]=r-(mid+)+;
tg[p<<]=tg[p<<|]=id;
wd[p<<]=wd[p<<|]=id+'a';
fg[p<<]=fg[p<<|]=;
tg[p]=-;
}
int mid=(l+r)>>;
if(ll<=mid)
cover(p<<,l,mid,ll,rr,id);
if(rr>mid)
cover(p<<|,mid+,r,ll,rr,id);
int fgg=;
for(int i=;i<;++i){
cnt[p][i]=cnt[p<<][i]+cnt[p<<|][i];
fgg+=(cnt[p]!=);
}
fg[p]=(fgg==);
}
void dfs(int p,int l,int r){
if(l==r){
printf("%c",wd[p]);
return;
}
if(tg[p]!=-){
int id=tg[p];
int mid=(l+r)>>;
clr(cnt[p<<]);
clr(cnt[p<<|]);
cnt[p<<][id]=mid-l+;
cnt[p<<|][id]=r-(mid+)+;
tg[p<<]=tg[p<<|]=id;
wd[p<<]=wd[p<<|]=id+'a';
fg[p<<]=fg[p<<|]=;
tg[p]=-;
}
int mid=(l+r)>>;
dfs(p<<,l,mid);
dfs(p<<|,mid+,r);
}
int main(){
scanf("%d%d",&N,&M);
char c=getchar();
int len=;
while(c<'a' || c>'z')
c=getchar();
while(c<='z' && c>='a'){
s[++len]=c;
c=getchar();
}
bt(,,N);
for(int i=;i<=M;++i){
int l,r,opt;
scanf("%d%d%d",&l,&r,&opt);
clr(t);
get(,,N,l,r,t);
if(opt==){
for(int i=;i>=;--i){
if(t[i])
cover(,,N,l,l+t[i]-,i);
l+=t[i];
}
}
else{
for(int i=;i<;++i){
if(t[i])
cover(,,N,l,l+t[i]-,i);
l+=t[i];
}
}
}
dfs(,,N);
}
正常AC代码
#include<bits/stdc++.h>
#define MAXN 100005
#define cri const register int
#define pt puts("----------------")
using namespace std;
int now[];
char s[MAXN];
struct Seg_tree{
int t[MAXN*][],f[MAXN*];
#define ls k<<1
#define rs k<<1|1
void change(cri k,cri l,cri r,cri gl,cri gr,cri val)
{
if(l>=gl&&r<=gr)
{
memset(t[k],,sizeof(t[k]));
t[k][val]=r-l+;
f[k]=val;
return ;
}
register int mid=l+r>>;
if(f[k])
{
register int mid=l+r>>;
memset(t[ls],,sizeof(t[ls]));
memset(t[rs],,sizeof(t[rs]));
register int p=f[k];f[k]=;
t[ls][p]=mid-l+;
t[rs][p]=r-mid;
f[ls]=f[rs]=p;
}
if(gl<=mid)change(ls,l,mid,gl,gr,val);
if(gr>mid)change(rs,mid+,r,gl,gr,val);
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
}
void query(cri k,cri l,cri r,cri gl,cri gr)
{
if(l>=gl&&r<=gr)
{
for(register int i=;i<=;i++)now[i]+=t[k][i];
return ;
}
register int mid=l+r>>;
if(f[k])
{
register int mid=l+r>>;
memset(t[ls],,sizeof(t[ls]));
memset(t[rs],,sizeof(t[rs]));
register int p=f[k];f[k]=;
t[ls][p]=mid-l+;
t[rs][p]=r-mid;
f[ls]=f[rs]=p;
}
if(gl<=mid)query(ls,l,mid,gl,gr);
if(gr>mid)query(rs,mid+,r,gl,gr);
return ;
}
void Build(cri k,cri l,cri r)
{
if(l==r)
{
t[k][s[l-]-'a'+]=;
return ;
}
register int mid=l+r>>;
Build(ls,l,mid);
Build(rs,mid+,r);
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
t[k][]=t[ls][]+t[rs][];
}
}T;
inline int Rd()
{
register int x=,f=;register char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-;c=getchar();}
return x*f;
}
int n,m;
int main()
{
scanf("%d%d%s",&n,&m,s);
T.Build(,,n);
while(m--)
{
memset(now,,sizeof(now));
register int l,r,x,t,k;
l=Rd();r=Rd();x=Rd();
k=l;
T.query(,,n,l,r);
if(x)
{
t=;
while(t<=)
{
while(!now[t]&&t<=)++t;
T.change(,,n,k,k+now[t]-,t);
k+=now[t];
now[t]=;
}
}
else
{
t=;
while(t>=)
{
while(!now[t]&&t>=)--t;
T.change(,,n,k,k+now[t]-,t);
k+=now[t];
now[t]=;
}
}
}
for(int i=;i<=n;i++)
{
memset(now,,sizeof(now));
T.query(,,n,i,i);
for(int j=;j<=;j++)
if(now[j])
{
putchar('a'+j-);
break;
}
}
puts("");
return ;
}
我的AC代码。
#include<cstdio>
char s[],bucx[];int bucr[],buc[],n,m;
main(){
scanf("%d%d%s",&n,&m,s+);bucr[n+]=n+;
for(int i=;i<=n;++i)bucr[i]=i,bucx[i]=s[i];
for(int i=,l,r,x;i<=m;++i){
scanf("%d%d%d",&l,&r,&x);
int j;for(j=l;!bucr[j];--j);
int k=bucr[j]+;if(j!=l)buc[bucx[j]]+=bucr[j]-l+,bucr[j]=l-;else k=j;
while(bucr[k]<=r){
buc[bucx[k]]+=bucr[k]-k+;
int lst=k;k=bucr[k]+;bucr[lst]=;
}
if(k<=r)buc[bucx[k]]+=r-k+,bucr[r+]=bucr[k],bucx[r+]=bucx[k],bucr[k]=;
if(x)for(char ch='a';ch<='z';++ch)if(buc[ch])bucr[l]=l+buc[ch]-,bucx[l]=ch,l=bucr[l]+,buc[ch]=;
if(!x)for(char ch='z';ch>='a';--ch)if(buc[ch])bucr[l]=l+buc[ch]-,bucx[l]=ch,l=bucr[l]+,buc[ch]=;
}
for(int i=;i<=n;i=bucr[i]+)for(int j=i;j<=bucr[i];++j)putchar(bucx[i]);
}
300ms做法
(Orz wd暴力QJ神仙打法)
T2:matrix
dp状态设的很神 f[i][j]表示前i列满足j个有区间且满足题意的方案数
先设ls[i]表示右端点在前i列的左区间的方案数,rs[i]表示左端点在前i列的右区间的方案数
然后就可以转移了,考虑列数增还是不增
不增:f[i+1][j]+=f[i][j]
增:f[i+1][j+1]+=f[i][j]*(rs[i+1]-j)
注意左侧区间我们并没有考虑,实际考虑,供我们选的列有i-j个,前一个状态已经选了ls[i-1]个,新增状态有ls[i]-ls[i-1]个。
用新增状态塞满可选状态并要考虑顺序,同时还有一个合法状态的判定然后就没啦
说起来很简单,但状态真的难想,但也不无道理。
这个题紧紧扣住列,而与具体是哪行无关,所以i,j都与列有关,同时为了方便转移,我们抓住一侧的区间,状态及其转移就显然了。
还是要抓住题目核心性质。
#include<bits/stdc++.h>
#define MAXN 3005
#define int long long
using namespace std;
const int mod=;
int f[MAXN][MAXN],ls[MAXN],rs[MAXN],l[MAXN],r[MAXN],A[MAXN][MAXN];
signed main()
{
int n,m;
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%lld%lld",&l[i],&r[i]);
ls[l[i]]++;rs[r[i]]++;
}
for(int i=;i<=m;i++)ls[i]+=ls[i-],rs[i]+=rs[i-];
A[][]=A[][]=;f[][]=;
for(int i=;i<=m;i++)
{
A[i][]=;A[i][]=i;
for(int j=;j<=i;j++)
A[i][j]=A[i][j-]*(i-j+)%mod;
}
for(int i=;i<=m;i++)
{
for(int j=;j<=min(i,n);j++)
{
if(i-j<ls[i])break;
(f[i][j]*=A[i-j-ls[i-]][ls[i]-ls[i-]])%=mod;
(f[i+][j]+=f[i][j])%=mod;
(f[i+][j+]+=f[i][j]*max(0ll,rs[i+]-j))%=mod;
}
}
cout<<f[m][n]<<endl;
return ;
}
T3:big
这题的难点在于如何转化题意
这个式子实际上就是x的逻辑左移,然后后面就显然了,开一颗Trie树,求最大值即可
#include<bits/stdc++.h>
#define re register
using namespace std;
const int MAXN=;
int n,maxx,val,sum[MAXN],psum[MAXN],num;
int ch[MAXN*][],tot;
void insert(const int x)
{
re int p=;
for(int i=n-;i>=;i--)
{
re int k=(x>>i)&;
if(!ch[p][k])ch[p][k]=++tot;
p=ch[p][k];
}
return ;
}
void Getans(const int x,int val,int dep)
{
if(!ch[x][]&&!ch[x][])
{
if(val==maxx)num++;
else if(val>maxx)maxx=val,num=;
return ;
}
if(ch[x][]&&ch[x][]){
Getans(ch[x][],val,dep+);
Getans(ch[x][],val,dep+);
return ;
}
if(!ch[x][]||!ch[x][]){
Getans(ch[x][]|ch[x][],val+(<<(n-dep-)),dep+);
}
return ;
}
int main()
{
int m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
register int a,k=;scanf("%d",&a);
sum[i]=sum[i-]^a;
if((a>>(n-))&)k=;
(k+=a<<)&=((<<n)-);
psum[i]=psum[i-]^k;
}
for(int i=;i<=m;i++)
insert(psum[i]^(sum[m]^sum[i]));
Getans(,,);
cout<<maxx<<endl<<num<<endl;
return ;
}
总结:
1.分析题目核心性质
2.转化题意
3.卡常
NOIP模拟测试11的更多相关文章
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
- [NOIP模拟测试11] 题解
A.string 和河北的一道省选题很像.考场上写的暴力桶排,正解其实就是优化一下这个思路. 开线段树维护字符串中每个字母出现的次数.对于每条询问,区间查询.区间赋值维护即可. 另外,本题卡常严重,正 ...
- NOIP模拟测试11「string·matrix·big」
打的big出了点小问题,maxx初值我设的0然后少了10分 第二题暴力打炸 第一题剪了一些没用的枝依然40分 总分70 这是一次失败的考试 string 想到和序列那个题很像,但我没做序列,考场回忆学 ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- NOIP模拟测试17&18
NOIP模拟测试17&18 17-T1 给定一个序列,选取其中一个闭区间,使得其中每个元素可以在重新排列后成为一个等比数列的子序列,问区间最长是? 特判比值为1的情况,预处理比值2~1000的 ...
- NOIP模拟测试1(2017081501)
好,今天是cgg第一次举行模拟测试,希望各位支持. 时间限制:2小时 题目链接: 题目一:水得都没名字了 题目二:车站 题目三:选数 不要觉得2小时太少,我的题目很良心,都很简单. 答案可以在模拟测试 ...
随机推荐
- spring boot使用vue+vue-router构建单页面应用
spring boot http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/ vue https: ...
- ActiveMQ学习总结------原生实战操作(下)03
本篇将继续延续上一篇的内容,作为知识补充篇,为接下来我们学习spring整合ActiveMQ打好基础 本篇主要学习内容: 1.ActiveMQ 队列服务监听 2.ActiveMQ Topic模型 回顾 ...
- Kylin构建Cube过程详解
1 前言 在使用Kylin的时候,最重要的一步就是创建cube的模型定义,即指定度量和维度以及一些附加信息,然后对cube进行build,当然我们也可以根据原始表中的某一个string字段(这个字段的 ...
- 初识Django,了解一下大概流程
学习Django一个礼拜了,对其有了一个大概的了解,自己画了一个简单的图,虽然有点丑,但是基本上已经把自己所想已经表达 写完这篇随笔之后发现自己逻辑表述的有点不太清晰,有点乱,哪里不对,希望各位指正 ...
- python编程基础之十三
列表的通用操作: list1 = [43, 65, 76, 6] list2 = [45, 77, 90, 11, 2, 4, 66] print(list1+ list2) # 列表组合 prin ...
- windows显示文件后缀名
win+E 进入到计算机 点击组织 点击文件夹和搜索选项 先点击查看,然后去掉勾选隐藏已知文件类型的扩展名
- 毕业设计过程中的一些学习Android网站
安卓巴士:http://www.apkbus.com/CSDN:(下载资源)http://www.csdn.net/?ref=toolbar博客园:http://www.cnblogs.com/极客学 ...
- css 文字间距
letter-spacing : 字与字之间的距离 text-indent : 行的抬头间距 line-height : 行高度
- 从Go语言编码角度解释实现简易区块链
区块链技术 人们可以用许多不同的方式解释区块链技术,其中通过加密货币来看区块链一直是主流.大多数人接触区块链技术都是从比特币谈起,但比特币仅仅是众多加密货币的一种. 到底什么是区块链技术? 从金融学相 ...
- Java Web 学习(1) —— Servlet
Java Web 学习(1) —— Servlet 一. 什么是 Servlet Java Servlet 技术是Java体系中用于开发 Web 应用的底层技术. Servlet 是运行在 Servl ...