首页 > 其他分享 >暑假集训csp提高模拟21

暑假集训csp提高模拟21

时间:2024-08-15 21:04:35浏览次数:5  
标签:21 int void long csp FILE using 集训 define

赛时rank 47,T1 20,T2 0,T3 30,T4 45

赛时最后想到了T1的正解,可惜没有打出来。

整场比赛都在死磕T1的神秘构造,导致本来可以AC的T2没有写,开题的策略不行,太容易死磕了。

T1 黎明与萤火

Destruction of a Tree

贪心构造。

先给一组数据

Input:
5
0 1 2 3 4

Output:
YES
2
4 
1
3
5

通过这组数据可以发现,从叶子节点点往上找可以删去的删去是符合条件的。

考虑证明为什么。

根据题意,当\(n\)为偶数时,答案一定为NO,因为我们一次只能删掉偶数条边,所以最后一定有一条边余下。

那么就考虑到,对于每一颗子树,只有当它的大小为奇数时,才可以删去。

假设有一个节点\(x\)

如果它的所有子树都为奇数,那么只有它有奇数颗子树时,这颗子树才合法。

所以\(x\)的度数为\(奇数+1=偶数\)符合题意。

所以就从深度大的往深度小的搜索即可

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#ifdef LOCAL
    FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
    // FILE *ErrFile=errfile("err.err");
#else
    FILE *Infile = stdin,*OutFile = stdout;
    //FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 2e5 + 10;
struct EDGE{int to,next;}edge[N<<1];
int head[N],cnt;
inline void add(int u,int v){
    edge[++cnt] = {v,head[u]};
    head[u] = cnt;
}
int n,d[N],fa[N];
stack<int> s;
vector<int> ans;
bitset<N> vis;
void dfs1(int x,int f){
    fa[x] = f;s.push(x);
    for(int i = head[x]; i;i = edge[i].next){
        int y = edge[i].to;
        if(y == f) continue;
        dfs1(y,x);
    }
}
void dfs2(int x){
    vis[x] = true;
    ans.emplace_back(x);
    for(int i = head[x]; i;i = edge[i].next){
        int y = edge[i].to;d[y]--;
        if(y == fa[x] || vis[y]) continue;
        if(d[y] % 2 == 0) dfs2(y);
    }
}
inline void solve(){
    cin>>n;
    for(int i = 1,fa;i <= n; ++i){
        cin>>fa;
        if(!fa) continue;
        add(i,fa);add(fa,i);
        d[i]++,d[fa]++;
    }
    dfs1(1,0);
    while(s.size()){
        int x = s.top();s.pop();
        if(d[x] % 2 == 0) dfs2(x);
    }
    if(ans.size() == n){
        cout<<"YES\n";
        for(auto i : ans) cout<<i<<'\n';
    }
    else cout<<"NO\n";
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

T2 Darling Dance

Edge Deletion

简单题。

建出以1为根的最短路树,bfs保留即可。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#ifdef LOCAL
    FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
    // FILE *ErrFile=errfile("err.err");
#else
    FILE *Infile = stdin,*OutFile = stdout;
    //FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 3e5 + 10;
int n,m,k;
struct EDGE{int to,next,w;}edge[N<<1];
int head[N],cnt;
inline void add(int u,int v,int w){
    edge[++cnt] = {v,head[u],w};
    head[u] = cnt;
}
int u[N],v[N],w[N],fa1[N],fa2[N];
#define pii pair<int,int>
#define mk make_pair
bitset<N> vis;
ll dist[N];
inline void dijkstra(int s){
    vis.reset();
    memset(dist,0x3f,sizeof dist);
    priority_queue<pii,vector<pii>,greater<pii> > q;
    dist[s] = 0;
    q.push(mk(0,s));
    while(q.size()){
        int x = q.top().second;q.pop();
        if(vis[x]) continue;
        vis[x] = true;
        for(int i = head[x]; i;i = edge[i].next){
            int y = edge[i].to;
            if(dist[y] > dist[x] + edge[i].w){
                dist[y] = dist[x] + edge[i].w;
                fa1[y] = x;
                fa2[y] = i;
                q.push(mk(dist[y],y));
            }
        }
    }
}
vector<int> son[N];
inline void solve(){
    cin>>n>>m>>k;
    for(int i = 1,u,v,w;i <= m; ++i){
        cin>>u>>v>>w;
        add(u,v,w),add(v,u,w);
    }
    dijkstra(1);
    for(int i = 2;i <= n; ++i) 
        son[fa1[i]].emplace_back(i);
    vector<int> ans;
    queue<int> q;
    q.push(1);
    while(q.size() && ans.size() <= k){
        int x = q.front();q.pop();
        for(auto y : son[x]){
            if(ans.size() == k)break;
            ans.push_back((int)(ceil(fa2[y]/2.0)));
            q.push(y);
        }
    }
    cout<<ans.size()<<'\n';
    for(auto i : ans) cout<<i<<' ';
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

T3 Non-breath oblige

[Ynoi2012] NOIP2015 充满了希望

将线段树维护值转化为维护时间戳。

将询问离线,既然询问是查询\([l,r]\)中所有询问的值的和,那么这个答案显然可以转化成\([1,r]\)的答案\(-[1,l)\)的答案,树状数组维护即可

卡卡常就过了。

线段树变成珂朵莉树也可以。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#ifdef LOCAL
    FILE *InFile = infile("in.in"),*OutFile = outfile("out.out");
    // FILE *ErrFile=errfile("err.err");
#else
    FILE *Infile = stdin,*OutFile = stdout;
    //FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#define getchar getchar_unlocked
#define putchar putchar_unlocked
template<class T>
inline void read(T &x){
    x = 0;
    char s = getchar();
    for(;s < '0' || '9' < s;s = getchar());
    for(;'0' <= s && s <= '9';s = getchar())
        x = (x<<1) + (x<<3) + (s^48);
}
template<class T>
void write1(T x){
    if(x > 9) write1(x/10);
    putchar(x%10 + '0');
}
template<class T>
inline void write(T x){
    if(x < 0) x = -x,putchar('-');
    write1(x);
}
const int N = 1e6 + 10;
int n,m,q;
struct node{
    int op,l,r,x;
}a[N];
class Segment_Tree{
private:
    struct segment_tree{
        int l,r,val,lazy;
#define l(k) tree[k].l
#define r(k) tree[k].r
#define val(k) tree[k].val
#define lazy(k) tree[k].lazy
    }tree[N<<2];
    inline void pushdown(int k){
        if(lazy(k)){
            val(k<<1) = val(k<<1|1) = lazy(k);
            lazy(k<<1) = lazy(k<<1|1) = lazy(k);
            lazy(k) = 0;
        }
    }
public:
    void build(int k,int l,int r){
        l(k) = l,r(k) = r;val(k) = lazy(k) = 0;
        if(l == r) return val(k) = 0,void();
        int mid = (l + r) >> 1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
    }
    void update(int k,int l,int r,int val){
        if(l <= l(k) && r(k) <= r) return val(k) = lazy(k) = val,void();
        pushdown(k);
        int mid = (l(k) + r(k)) >> 1;
        if(l <= mid) update(k<<1,l,r,val);
        if(r > mid) update(k<<1|1,l,r,val);
    }
    int query(int k,int pos){
        if(l(k) == r(k)) return val(k);
        pushdown(k);
        int mid = (l(k) + r(k)) >> 1;
        if(pos <= mid) return query(k<<1,pos);
        else return query(k<<1|1,pos);
    }
}T;
vector<pair<int,int> > que[N];
class BIT{
private:
    ll tree[N];
    #define lowbit(x) (x&(-x))
public:
    int mx;
    inline void update(int pos,int val){
        if(!pos) return;
        for(int i = pos;i <= mx;i += lowbit(i))
            tree[i] += val;
    }
    inline ll query(int pos){
        ll res = 0;
        for(int i = pos; i;i -= lowbit(i))
            res += tree[i];
        return res;
    }
}Tr;
ll ans[N];
inline void solve(){
    read(n),read(m),read(q);
    T.build(1,1,n);
    Tr.mx = m;
    int tot = 0;
    for(int i = 1;i <= m; ++i){
        read(a[i].op);
        if(a[i].op == 2){
            tot++;
            read(a[i].l),read(a[i].r),read(a[i].x);
            T.update(1,a[i].l,a[i].r,i);
        }
        if(a[i].op == 1){
            read(a[i].l),read(a[i].r);
            int res1 = T.query(1,a[i].l);
            int res2 = T.query(1,a[i].r);
            T.update(1,a[i].l,a[i].l,res2);
            T.update(1,a[i].r,a[i].r,res1);
        }
        if(a[i].op == 3) read(a[i].x),a[i].r = T.query(1,a[i].x);
    }
    for(int i = 1,l,r;i <= q; ++i){
        read(l),read(r);
        que[r].emplace_back(make_pair(l-1,i));
    }
    for(int i = 1;i <= m; ++i){
        if(a[i].op == 3) Tr.update(a[i].r,a[a[i].r].x);
        for(auto j : que[i])
            ans[j.second] = Tr.query(i) - Tr.query(j.first);
    }
    for(int i = 1;i <= q; ++i) write(ans[i]),putchar('\n');
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

T4 妄想感伤代偿联盟

正解好像很唐,不会。

挂一下。

image

打了一个记忆化加上一个数据点分治。

比某些人的正解快

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using ll = long long;
const int N = 6e5 + 10;
const ll base = 2333,mod = 1e9 + 3579;
string s[N];
int n,m,len[N];
vector<ll > H[N];
vector<ll > h[N];
ll pw[N];
unordered_map<int,int> mp[N];
int Ans[5000][5000],to[N];
inline void solve(){
    pw[0] = 1;
    for(int i = 1;i < N;++i) pw[i] = pw[i - 1] * base % mod;
    cin>>n>>m;
    for(int i = 1;i <= n; ++i){
        cin>>s[i];
        len[i] = s[i].length();
    }
    vector<int> big;big.clear();
    for(int i = 1;i <= n; ++i){
        H[i].push_back(0);
		for(int j=0;j<len[i];j++){
			H[i].push_back((H[i].back()*base%mod+s[i][j]-'a'+1)%mod);
		}
        h[i].push_back(0);
		for(int j=len[i]-1,k=0;j>=0;j--,k++){
			h[i].push_back((h[i].back()+(s[i][j]-'a'+1)*pw[k]%mod)%mod);
		}
        if(len[i] > 1000) big.emplace_back(i),to[i] = big.size()-1;
        // for(auto j:H[i]) cout<<j<<' ';
        // cout<<'\n';
        // for(auto j:h[i]) cout<<j<<' ';
        // cout<<"\n\n";
    }
    int x,y;
    int siz = big.size();
    for(int i = 0;i < siz; ++i){
        for(int j = 0;j < siz; ++j){
            if(i == j) continue;
            int x = big[i],y = big[j];
            int l = 0,r = min(len[x],len[y]),ans = 0;
            for(int mid = r;mid >= l; --mid){
                if(h[x][mid] == H[y][mid]){
                    ans = mid;break;
                }
            }
            Ans[i][j] = ans;
        }
    }
    while(m--){
        cin>>x>>y;
        if(x > n || y > n){cout<<"0\n";continue;}
        if(x == y){cout<<len[x]<<'\n';continue;}
        int l = 0,r = min(len[x],len[y]),ans = 0;
        if(r > 1000){
            cout<<Ans[to[x]][to[y]]<<'\n';
            continue;
        }
        if(mp[x].find(y) != mp[x].end()){
            cout<<mp[x][y]<<'\n';
            continue;
        }
        if(min(len[x],len[y])<=1000){
			for(int i=min(len[x],len[y]);i>=0;i--){
				if(h[x][i]==H[y][i]){
					ans = i;
					break;
				}
			}
		}
        cout<<(mp[x][y] = ans)<<'\n';
    }
}
signed main(){
    #ifdef LOCAL
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
    cin.tie(nullptr)->sync_with_stdio(false);
    cout.tie(nullptr)->sync_with_stdio(false);
    solve();
}

标签:21,int,void,long,csp,FILE,using,集训,define
From: https://www.cnblogs.com/hzoi-Cu/p/18361807

相关文章

  • 2024暑假集训测试25
    前言比赛链接。一上来就感觉T4最可做,发现T4题面假了,去找学长改了,让后第一反应二分哈希,怎么调大样例都过不去,异常上火,狂调一个半小时才想起来丫的这玩意儿没有单调性,然后就崩了。结果T4string用死了挂成\(0\)分了还。T2是水板子但是不会那个板子,心态者了T1也没搞......
  • 『模拟赛』暑假集训CSP提高模拟21
    Rank意外地还凑合,本来以为这场要GG了。A.黎明与萤火原[CF963B]DestructionofaTree签,勉强签了。开始脑子乱,胡乱打了一个含有3个dfs函数,每个函数里含两次遍历链式前向星,不负众望大样例T了。后来也是摸着摸着就出正解了,先一遍dfs跑出基本的数据,然后再一遍df......
  • NSSCTF [SWPUCTF 2021 新生赛]easyupload3.0
    进入页面,是一个文件上传,放个图片马上去,用bp抓包正常进行文件上传,发现一般的后缀都被过滤了 使用.user.ini后门但好像也不行。没有什么头绪,去网上看看大佬们怎么做的。发现他们是通过修改.htaccess文件的配置来实现后门,之前也只了解过这个后缀,先去看看是干嘛的,具体怎么用。大佬......
  • [赛记] 暑假集训CSP提高模拟20 21
    Kanon40pts签到题,但是不会,所以打了暴力;正解时考虑相邻两个雪球,只有两种情况:它们的覆盖区间有交集或无交集,那么如果我们找出了无交集的最后一天,我们就很容易判断剩下的一堆雪该被谁拿走,于是我们二分找出这一天即可;赛时确实想不到二分时间复杂度:$\Theta(n\logn)$;点击查看......
  • CSP21
    总结:两个题的checker我都自己写了一个,MD,耽误太多时间了,\(Linux\)的\(checker\)使用要加g++checker.cpp-o程序名这题,性质题,首先发现一个树\(n-1\)条边,每次删偶数条边,所以\(n\)必须是奇数,其次我们发现优先删去深度深的点较为优,删完后,我们发现还剩下一些散点散树,再\(dfs\)一......
  • 『模拟赛』暑假集训CSP提高模拟21
    『模拟赛』暑假集训CSP提高模拟21终于没RE了!不枉我辛辛苦苦调了几个小时...(但是暴力没打完...(逃T1黎明与萤火DFS序乱糊+贪心注意要先消除叶子结点。Elaina'sCodeintn,fa[N],rdeg[N],hd[N],idx,ans[N],cnt;boolvis[N];stack<int>sta;structEDGE{ intnxt,to;}......
  • EndNote21.4安装教程(最新版)
    下载链接:https://docs.qq.com/doc/DSVZXTVRvYXdEd21q软件介绍、EndNote文献管理软件是由科睿唯安公司开发的文献管理软件,可用于帮助研究人员管理和组织参考文献、引用和注释,从文献检索、组织科研活动、撰写论文,到发表文章和共享科研成果,助力机构用户加速科研流程。EndNote......
  • 暑假集训CSP提高模拟21
    暑假集训CSP提高模拟21组题人:@Muel_imj\(T1\)P241.黎明与萤火\(10pts\)原题:CF963BDestructionofaTree部分分\(10pts\):生成\(1\simn\)的全排列然后依次判断。\(20pts\):输出NO。正解叶子节点的度数为\(1\),不能直接删除,只能先删除父亲节点后再......
  • 2024.8.14 总结(集训)
    依然是TQX来讲字符串。/bx/bx/bx属于是两个上午速通字符串里一些重要的内容。上课时只有manacher和PAM是我有点听懂了的。于是下午看TQX的博客学了PAM,看之前看过的博客复习了下SAM,给why讲了些、和他讨论了PAM,AC了洛谷上的PAM板子,看TQX的PPT学了manache......
  • 『模拟赛』暑假集训CSP提高模拟20
    Rank有点可惜,暴力打满就并列Rank1了。A.Kanon原[JOI2021Final]雪玉签。考虑到每两个球之间的距离是恒不变的,因此我们可以通过找到每个球控制的边界得到答案,每个区间正好可以得出左边球的右边界和右边球的左边界。记录每个区间的标号和长度,按长度升序sort一遍,然......