NOIP系列题目
Harp_Skier · · 个人记录
1表示没看题解,2表示看了题解
NOIP2023 三值逻辑
赛场上没写出来。无语。一等没了。
观察到可以模拟前面赋值的过程,然后连边。
记得连双向边!这不会对判环造成影响!赛场就在这里写错了。
发现每个点的出边数量
所以每个连通块同边数
可以发现,边数为
对于边数为
计算siz可以用并查集,最好别用dfs暴力找,我考场就是这样挂的。
时间复杂度合理的情况下,应该使用适当的方法降低代码实现难度才对。
发现F形其实是C形向上延申,反过来想,F形只需要将右侧长度乘上下方C形的总方案数即可,十分容易计算。
设一个点向右拓展的最大长度为
清数组的时候注意,多清空几位不会怎么样,不要因为访问了n+1和0,并且默认它们是0而挂分,实在不行就memset。(1)
NOIP 2012 国王游戏
(2)
NOIP 2000 乘积最大
考虑dp,设
NOIP 2007 矩阵取数游戏
不想改题了,本来想认真做道蓝题。但是这题实在是评不上蓝题。
发现行与行之间独立,考虑分开做,发现只从左右两边选数,直接区间dp是很快的。
具体的,设
显然最后这一行的答案就是
考虑转移。
不想动脑。。。
记搜!!
这样搜到
必须贴一个我5min码完一发A的代码。
#include<bits/stdc++.h>
using namespace std;
#define ll __int128_t
const int N=101;
int n,m;
int a[N];
ll f[N][N],sum;
inline ll get(int b){
ll res=1,a=2;
while(b){
if(b&1)res=res*a;
a=a*a;
b>>=1;
}
return res;
}
inline ll maxx(ll A,ll B){return A>B?A:B;}
inline void dfs(int l,int r,int step,ll nsum){
if(f[l][r]>=nsum)return ;
f[l][r]=nsum;
if(l==r){sum=maxx(sum,f[l][r]+a[l]*get(step));return ;}
dfs(l+1,r,step+1,f[l][r]+a[l]*get(step));
dfs(l,r-1,step+1,f[l][r]+a[r]*get(step));
}
#define pc putchar
inline void wt(ll x){
if(x<10)pc(x+'0');
else wt(x/10),pc(x%10+'0');
}
int main(){
scanf("%d%d",&n,&m);
ll ans=0;
while(n--){
for(int i=1;i<=m;++i)scanf("%d",&a[i]);
memset(f,-1,sizeof f);
sum=0;
dfs(1,m,1,0);
ans+=sum;
}
wt(ans);
return 0;
}
没看题解 111
不知道为什么最后一个点983ms,可能get函数里面不写logn的就会TLE。
NOIP 2020 排水系统
今天模拟赛做NOIP2020。
开题就发现这题拓扑,这也太明显了吧,水从入度为0的点流入。
考虑拓扑推答案,直接暴力推都是
比赛的时候开了ll没开__int128_t
100->60 麻
NOIP 2020 字符串匹配
比赛的时候被卡常了。麻。
令
有
考虑先枚举D,那么
考虑枚举i,这样C的左端点自然就出来了。
可以预处理出每个前后缀的
然后问题就变成了,对于前
典!GDKOI没写的问题现在又遇到了。
直接上树状数组即可,十分的“快”。
乍一看,这复杂度
就在我苦思冥想的时候,回来认真看了一下复杂度,我靠,
枚举i,D的时间是
BIT查询是log级别。
算了一下感觉可能可以
于是没有卡常dop
只拿到了84。
后来发现
时间就可以变成
可是怎么92分?咦?96???
评测机波动?
卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡卡常常常常常常常常常常常常常常常常
luogu上过了,gmoj没过,这是为什么捏?
后来还是把BIT删了,修改可以
这样时间就是
但是由于我人傻常数大,还是跑了793ms,别人比我快百倍,怎么办我好菜。
(2)
附:
BIT代码:
#include<bits/stdc++.h>
using namespace std;
const int N=5e6+2;
#define ll long long
#define ull unsigned long long
#define re register
int T,n;
char s[N];
ll ans;
inline int read(){
int res=0,f=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))res=(res<<1)+(res<<3)+(ch^48),ch=getchar();
return res*f;
}
const ull base=41;
int f[N],g[N];
ull h[N],b[N];
int t[31];
struct BIT{
int tr[N];
inline void clear(){for(re int i=0;i<=n;++i)tr[i]=0;}
inline int lowbit(re int x){return x&(-x);}
inline void ins(re int x){if(x==0){tr[0]++;return ;}while(x<=31){tr[x]++;x+=lowbit(x);}}
inline int qry(re int x){re int res=0;while(x){res+=tr[x];x-=lowbit(x);}return res+tr[0];}
}xxh;
int main(){
T=read();
b[0]=1;
for(re int i=1;i<=N;++i)b[i]=b[i-1]*base;
while(T--){
scanf("%s",s+1);
n=strlen(s+1);
for(re int i=1;i<=n;++i)h[i]=h[i-1]+b[i]*(s[i]-'a');
f[0]=0,g[n+1]=0;
for(re int i=0;i<=30;++i)t[i]=0;
for(re int i=1;i<=n;++i){
f[i]=f[i-1];
t[s[i]-'a']++;
if(t[s[i]-'a']%2==0)f[i]--;
else f[i]++;
}
for(re int i=0;i<=30;++i)t[i]=0;
for(re int i=n;i>=1;--i){
g[i]=g[i+1];
t[s[i]-'a']++;
if(t[s[i]-'a']%2==0)g[i]--;
else g[i]++;
}
vector<int>xh;
ans=0ll;
xxh.ins(f[1]);
for(re int i=2;i<n;++i){
re int len=i;
re int nxtl=i+1,nxtr=i+i;
xh.clear();
xh.push_back(i+1);
while(nxtr<=n){
if((h[i]-h[0])*b[nxtl]==(h[nxtr]-h[nxtl-1])*b[1])xh.push_back(nxtr+1),nxtl+=i,nxtr+=i;
else break;
}
for(re int j:xh)if(j<=n)ans+=xxh.qry(g[j]);
xxh.ins(f[i]);
}
printf("%lld\n",ans);
xxh.clear();
}
return 0;
}
无BIT代码
#pragma GCC optimize(2)
%:pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+2;
#define ll long long
#define ull unsigned long long
#define re register
int T,n;
char s[N];
ll ans;
inline int read(){
int res=0,f=1;
char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))res=(res<<1)+(res<<3)+(ch^48),ch=getchar();
return res*f;
}
const ull base=41;
int f[N],g[N];
ull h[N],b[N];
int t[31];
int tr[N];
#define pc putchar
inline void wt(ll x){
if(x<10)pc(x+'0');
else wt(x/10),pc(x%10+'0');
}
int main(){
freopen("string.in","r",stdin);
freopen("string.out","w",stdout);
T=read();
b[0]=1;
for(re int i=1;i<=N;++i)b[i]=b[i-1]*base;
while(T--){
scanf("%s",s+1);
n=strlen(s+1);
for(re int i=1;i<=n;++i)h[i]=h[i-1]+b[i]*(s[i]-'a');
f[0]=0,g[n+1]=0;
for(re int i=0;i<=30;++i)t[i]=0;
for(re int i=1;i<=n;++i){
f[i]=f[i-1];
t[s[i]-'a']++;
if(t[s[i]-'a']%2==0)f[i]--;
else f[i]++;
}
for(re int i=0;i<=30;++i)t[i]=0;
for(re int i=n;i>=1;--i){
g[i]=g[i+1];
t[s[i]-'a']++;
if(t[s[i]-'a']%2==0)g[i]--;
else g[i]++;
}
ans=0ll;
for(re int i=f[1];i<=26;++i)tr[i]++;
for(re int i=2;i<n;++i){
re int nxtl=i+1,nxtr=i+i;
ans+=tr[g[i+1]];
while(nxtr<n){
if((h[i]-h[0])*b[nxtl]==(h[nxtr]-h[nxtl-1])*b[1])ans+=tr[g[nxtr+1]],nxtl+=i,nxtr+=i;
else break;
}
for(re int j=f[i];j<=26;++j)tr[j]++;
}
wt(ans),puts("");
clear();
}
return 0;
}