CSP-S模拟11
CSP-S模拟11
A 锦标赛图表
签到题。栈或递归简单实现即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
string s;
int t[200],n;
int sum;
stack<int> sta;
signed main()
{
// #ifndef ONLINE_JUDGE
//chart
freopen("chart.in","r",stdin);
freopen("chart.out","w",stdout);
// #endif
cin>>s;
char c;
while(cin>>c)
{
n++;
int x;
cin>>x;
t[c]=x;
sum+=x;
}
// cout<<sum<<" "<<n<<"\n";
if(sum!=n-1) { cout<<"No";return 0; }
for(int i=0;i<s.size();i++)
{
// cout<<i<<"\n";
if(s[i]=='[') sta.push(s[i]);
else if(s[i]==']')
{
// int cnt=-1;
bool f=0;
char last,ans;
while(sta.top()!='[')
{
char nw=sta.top();
// cout<<nw<<"\n";
sta.pop();
if(!f) last=nw,f=1;
else
{
// cout<<(char)nw<<" - "<<(char)last<<"\n";
if(t[nw]<t[last]) swap(nw,last);
if(t[nw]==t[last]) { cout<<"No";return 0; }
t[nw]--;
ans=nw;
}
}
sta.pop();
sta.push(ans);
}
else if(s[i]=='-') continue;
else sta.push(s[i]);
}
// cout<<"\n\n----------------------------\n\n";
for(int i=0;i<150;i++)
{
if(t[i]) { cout<<"No";return 0; }
// cout<<(char)(i)<<" "<<t[i]<<"\n";
}
cout<<"Yes";
return 0;
}
B 质数中的质数
一半原题 luogu P1835 素数密度
一半稍微改一下筛质因子个数的 (前面忘了)筛 的模板即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1e6+5;
bitset<N+10> f;
int prime[N],cnt;
void init()
{
const int n=1e6;
f[0]=1;
f[1]=1;
for(int i=2;i<=n;i++)
{
if(f[i]) continue;
prime[++cnt]=i;
for(int j=i+i;j<=n;j+=i) f[j]=1;
}
// for(int i=1;i<=30;i++) cout<<prime[i]<<" ";
// cout<<"\n";
}
int l,r;
int num[N+100];
int last[N+100];
signed main()
{
// #ifndef ONLINE_JUDGE
freopen("prime.in","r",stdin);
freopen("prime.out","w",stdout);
// #endif
l=read();
r=read();
init();
for(int i=l;i<=r;i++) last[i-l]=i;
for(int i=1;i<=10000;i++)
{
int nw=1;
// int nw=prime[i];
for(int j=1;;j++)
{
nw*=prime[i];
if(nw>r) break;
int ql=l/nw;
if(nw*ql<l) ql++;
while(nw*ql<=r)
{
num[nw*ql-l]++;
last[nw*ql-l]/=prime[i];
ql++;
}
}
}
// for(int i=l;i<=r;i++)
// {
// cout<<"i="<<i<<" num="<<num[i-l]<<" last="<<last[i-l]<<"\n";
// }
int ans=0;
for(int i=l;i<=r;i++)
if(!f[num[i-l]+(last[i-l]>1)]) ans++;//,cout<<"i="<<i<<"\n";
cout<<ans;
return 0;
}
C 树分隔
设
\(dp[u][0]\) 表示 以 \(u\) 为根子树中不割点,点数 \(\ge k\) 的连通块数量。发现取值只会是 0/1。
\(dp[u][1]\) 表示 以 \(u\) 为根子树中只割根节点 \(u\) 的最大答案。
\(dp[u][2]\) 表示 以 \(u\) 为根子树中割一条链,其中一个端点为 \(u\) 的最大答案。
\(dp[u][3]\) 表示 以 \(u\) 为根子树中割两条链,转折点为 \(u\) 的最大答案(链两端点 lca 为 \(u\))。
设 \(siz[u]\) 为以 \(u\) 为根子树大小。
转移显然。
注意判断 2,3 能否转移,若不能则将 dp 值设为 \(-1\)。
#include<bits/stdc++.h>
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1e5+5;
int dp[N][4];
// 0:不选
// 1:只选点 i
// 2:选 1 条链
// 3:选 2 条链
int siz[N];
int n,k;
vector<int> E[N];
void clear()
{
memset(dp,0,sizeof(dp));
memset(siz,0,sizeof(siz));
for(int i=1;i<=n;i++) E[i].clear();
}
void dfs(int p,int fa)
{
// cerr<<p<<" "<<fa<<"\n";
siz[p]=1;
int sum=0;
for(int to:E[p])
{
if(to==fa) continue;
dfs(to,p);
siz[p]+=siz[to];
sum+=dp[to][0];
}
dp[p][1]=sum;
if(E[p].size()>1)
{
// if(p==4) cout<<sum<<" \n";
for(int to:E[p])// 选 1 条链
{
if(to==fa) continue;
dp[p][2]=max(dp[p][2],sum-dp[to][0]+max(dp[to][1],dp[to][2]));
}
}
else dp[p][2]=-1;
if(E[p].size()>2||(E[p].size()>1&&p==1))//选 2 条链
{
int ma1=-99999999,ma2=-99999999;
for(int to:E[p])
{
if(to==fa) continue;
int nw=-dp[to][0]+max(dp[to][1],dp[to][2]);
if(nw>ma1) ma2=ma1,ma1=nw;
else if(nw>ma2) ma2=nw;
}
dp[p][3]=sum+ma1+ma2;
}
else dp[p][3]=-1;
dp[p][0]=(siz[p]>=k);
}
void solve()
{
n=read();
k=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read();
E[u].push_back(v);
E[v].push_back(u);
}
// cerr<<"OLKDSBUIFADSDVB";
dfs(1,0);
int ans=0;
for(int i=1;i<=n;i++)
{
// cout<<"i="<<i<<" dp[i][0]="<<dp[i][0]<<" dp[i][1]="<<dp[i][1]<<" dp[i][2]="<<dp[i][2]<<" dp[i][3]="<<dp[i][3]<<" fa="<<(n-siz[i]>=k)<<"\n";
ans=max(ans,max(dp[i][2],dp[i][3])+(n-siz[i]>=k));
}
cout<<ans<<"\n";
clear();
}
signed main()
{
// #ifndef ONLINE_JUDGE
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
// #endif
int T=read();
while(T--) solve();
return 0;
}
D 传送带
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int Size=(1<<20)+1;
char buf[Size],*p1=buf,*p2=buf;
char buffer[Size];
int op1=-1;
const int op2=Size-1;
#define getchar() \
(tt == ss && (tt=(ss=In)+fread(In, 1, 1 << 20, stdin), ss == tt) \
? EOF \
: *ss++)
char In[1<<20],*ss=In,*tt=In;
inline int read()
{
int x=0,c=getchar(),f=0;
for(;c>'9'||c<'0';f=c=='-',c=getchar());
for(;c>='0'&&c<='9';c=getchar())
x=(x<<1)+(x<<3)+(c^48);
return f?-x:x;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int N=1e5+5;
struct Tr{
int maxn,lazy;
}t[N<<3];
void build(int l,int r,int p)
{
if(l==r)
{
t[p].maxn=l-1;
return;
}
int mid=(l+r)>>1,lp=(p<<1),rp=(p<<1)|1;
build(l,mid,lp);
build(mid+1,r,rp);
t[p].maxn=max(t[lp].maxn,t[rp].maxn);
// cout<<"["<<l<<","<<r<<"] "<<t[p].maxn<<"\n";
}
void pushdown(int p,int lp,int rp)
{
t[lp].lazy+=t[p].lazy;
t[rp].lazy+=t[p].lazy;
t[lp].maxn+=t[p].lazy;
t[rp].maxn+=t[p].lazy;
t[p].lazy=0;
}
void add(int l,int r,int sl,int sr,int k,int p)
{
if(sl<=l&&r<=sr)
{
t[p].lazy+=k;
t[p].maxn+=k;
return;
}
int mid=(l+r)>>1,lp=(p<<1),rp=(p<<1)|1;
if(t[p].lazy) pushdown(p,lp,rp);
if(sl<=mid) add(l,mid,sl,sr,k,lp);
if(sr>mid) add(mid+1,r,sl,sr,k,rp);
t[p].maxn=max(t[lp].maxn,t[rp].maxn);
}
int query(int l,int r,int sl,int sr,int p)
{
if(sl<=l&&r<=sr) return t[p].maxn;
int mid=(l+r)>>1,lp=(p<<1),rp=(p<<1)|1,ans=0;
if(t[p].lazy) pushdown(p,lp,rp);
if(sl<=mid) ans=query(l,mid,sl,sr,lp);
if(sr>mid) ans=max(ans,query(mid+1,r,sl,sr,rp));
t[p].maxn=max(t[lp].maxn,t[rp].maxn);
return ans;
}
signed main()
{
// #ifndef ONLINE_JUDGE
freopen("belt.in","r",stdin);
freopen("belt.out","w",stdout);
// #endif、
int n=read(),q=read(),maxn=0;
build(1,n,1);
for(int i=1;i<=q;i++)
{
int l=read(),r=read(),c=read(),op=read();
add(1,n,l,r,c,1);
maxn=max(maxn,r);
// cout<<maxn<<"\n";
if(op==1) cout<<query(1,n,1,maxn,1)<<"\n";
}
return 0;
}
以下是博客签名,正文无关
本文来自博客园,作者:Wy_x,转载请在文首注明原文链接:https://www.cnblogs.com/Wy-x/articles/19038661
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC-BY-NC-SA 4.0 协议)进行许可。

浙公网安备 33010602011771号