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;
}


posted @ 2025-08-14 22:10  Wy_x  阅读(35)  评论(3)    收藏  举报