首页 > 其他分享 >NOIP加赛2

NOIP加赛2

时间:2024-11-06 18:22:47浏览次数:2  
标签:inline NOIP int rep long using 加赛 ll

rank 15 T1 100,T2 80 ,T3 9,T4 0

本来不想交的,但快结束的时候回头看见huge在看着我就慌了。

T1 新的阶乘

签到题,将跑个类似于埃氏筛的东西就行了,时间复杂度\(O(n\log\log n)\)。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCAL
    FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
    FILE *InFile = freopen("factorial.in","r",stdin),*OutFile = freopen("factorial.out","w",stdout);
#endif
using ll = long long;using ull = unsigned long long;
using db = double;using ldb = long double;
#define int long long
const int N = 1e7 + 10;
vector<int> prime;
bool vis[N];int n;
inline void euler(int n){
	rep(i,2,n,1){
		if(!vis[i]) prime.emplace_back(i);
		for(auto j:prime){
			if(i * j > n) break;
			vis[i * j] = true;
		}
	}
}
int num[N],have[N];
inline void solve(){
	cin>>n;
	// if(n == 1) return cout<<"f(1)=1\n",void();
	euler(n);
	for(auto i:prime){
		int tot = 1,f = 1;
		for(int j = i;j <= n;j += i){
			num[i] += (have[j] = have[j/i] + 1)*(n - j + 1);
		}
		for(int j = i;j <= n; j += i) have[j] = 0;
	}
	cout<<"f("<<n<<")=";
	#define pii pair<int,int>
	#define mk make_pair
	vector<pii> ans;
	for(int i = 0;i < prime.size(); ++i)
		if(num[prime[i]]) ans.emplace_back(mk(prime[i],num[prime[i]]));
	for(int i = 0;i < ans.size(); ++i){
		if(ans[i].second == 1) cout<<ans[i].first;
		else cout<<ans[i].first<<'^'<<ans[i].second;
		if(i != ans.size() - 1) cout<<'*';
	}
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
	solve();
}

博弈树

80pts是记搜,随便打。

看到这个题先想打表找规律,发现当无法走的时候肯定是到了树的直径的一个顶点,所以先求出树的直径。

发现谁先从直径的一个端点走到另一个端点时谁就赢,所以如果先手一开始在直径的端点处就赢了。

如果先手一开始不在直径端点处,那么两个人肯定会在直径上磨蹭,大概就是你往左走n个我往右走n+1个这样,直到另一方到达直径的一个端点。

如果先手一开始不在直径上,那么一定会直接跳到直径上。然后就这样模拟,发现当且仅当先手一开始在直径中点时,后手会赢。

至于一棵树有好几条直径,都一样的。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCAL
    FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
    FILE *InFile = freopen("tree.in","r",stdin),*OutFile = freopen("tree.out","w",stdout);
#endif
using ll = long long;using ull = unsigned long long;
using db = double;using ldb = long double;
const int N = 1e5 + 10;
#define eb emplace_back
vector<int> e[N];
int n,q,dist[N],fa[N];
inline int bfs(int s){
    queue<int> q;bitset<N> vis;
    q.push(s);dist[s] = 1;vis.set(s);
    int ed = s,edn = 0;
    while(q.size()){
        int x = q.front();q.pop();
        for(int y:e[x]){
            if(vis[y]) continue;
            dist[y] = dist[x] + 1;
            fa[y] = x;q.push(y);
            vis[y] = true;
            if(dist[y] > edn) edn = dist[y],ed = y;
        }
    }
    return ed;
}
inline void solve(){
    cin>>n>>q;rep(i,1,n-1,1){int u,v;cin>>u>>v;e[u].eb(v);e[v].eb(u);}
    int s,t;t = bfs(s = bfs(1));
    int dis = dist[t];
    if(dis&1){
        int x = t;
        while(fa[x]){if(dist[x] <= (dis+1)/2) break;x = fa[x];}
        while(q--){
            int p;cin>>p;
            if(p == x) cout<<"Bob\n";
            else cout<<"Alice\n";
        }
    }
    else while(q--) cout<<"Alice\n";

}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    solve();
}

T3 划分

简单题,赛时没想到确实唐。

如果前k位没有1,那么最优解一定是第1个1之前选分至少\(k-1\)段,直接组合数。

反之,发现最优解一定是选出一段\(n-k+1\)的,剩下的每个数单独分一块。

考虑如何判断二进制数大小,用The classic problem那个二分+哈希的方法求出lcp长度,然后看后一位大小即可。

因为害怕被卡写的三模数哈希,然后喜提最裂解。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t;i += p)
#define drep(i,s,t,p) for(int i = s;i >= t;i -= p)
#ifdef LOCAL
    FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
    FILE *InFile = freopen("divide.in","r",stdin),*OutFile = freopen("divide.out","w",stdout);
#endif
using ll = long long;using ull = unsigned long long;
using db = double;using ldb = long double;
const int N = 2e6 + 10,mod = 998244353;
struct ThreeModHash{
    ll p1[N],h1[N];const ll m1 = 2432021027;
    ll p2[N],h2[N];const ll m2 = 998244353;
    ll p3[N],h3[N];const ll m3 = 1e9+3579;
    inline void init(char *s){
        int n = strlen(s+1);
        p1[0] = p2[0] = p3[0] = 1;
        rep(i,1,n,1) p1[i] = 1ll*p1[i-1]*2707%m1;
        rep(i,1,n,1) p2[i] = 1ll*p2[i-1]*2%m2;
        rep(i,1,n,1) p3[i] = 1ll*p3[i-1]*233%m3;
        rep(i,1,n,1) h1[i] = (h1[i-1]*2707+s[i])%m1;
        rep(i,1,n,1) h3[i] = (h3[i-1]*233+s[i])%m3;
        rep(i,1,n,1) h2[i] = (h2[i-1]*2+s[i]-'0')%m2;
    }
    inline ll get1(int l,int r){return (h1[r] - h1[l-1]*p1[r-l+1]%m1+m1)%m1;}
    inline ll get2(int l,int r){return (h2[r] - h2[l-1]*p2[r-l+1]%m2+m2)%m2;}
    inline ll get3(int l,int r){return (h3[r] - h3[l-1]*p3[r-l+1]%m3+m3)%m3;}
    inline bool cmp(int l1,int r1,int l2,int r2){
        return (get1(l1,r1) == get1(l2,r2) && get2(l1,r1) == get2(l2,r2) && get3(l1,r1) == get3(l2,r2));
    }
}hs;
namespace Combination{
    const int mod = 998244353;
    inline int power(int a,int b,int mod){
        int res = 1;
        for(;b;b >>= 1,a = 1ll*a*a%mod)
            if(b&1) res = 1ll*res*a%mod;
        return res;
    }
    inline int Inv(int a){return power(a,mod-2,mod);}
    int fac[N],inv[N];
    inline void init(int n){
        fac[0] = 1;rep(i,1,n,1) fac[i] = 1ll*fac[i-1]*i%mod;
        inv[n] = Inv(fac[n]);drep(i,n-1,0,1) inv[i] = 1ll*inv[i+1]*(i+1)%mod;
    }
    inline int C(int n,int m){return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;}
}using Combination::C;
int n,k,fst,sum[N];char s[N];
inline void solve1(){
    int len = n - k,ans = 0,p = fst;
    rep(i,fst,k,1) if(sum[i + len - 1] - sum[i - 1] == len) ans++,p = i;
    if(ans){
        cout<<(hs.get2(p,p+len-1)*2+sum[n]-len+mod)%mod<<' '<<ans<<'\n';
        return;
    }
    ans = 1;
    rep(i,fst + 1,k,1){
        int l = 1,r = len + 1,res = 1;
        while(l <= r){
            int mid = (l + r) >> 1;
            if(hs.cmp(i,i+mid-1,p,p+mid-1)) res = mid,l = mid + 1;
            else r = mid - 1;
        }
        // l = res;
        if(res == len + 1) ans++;
        if(l < len && s[p+l-1] < s[i+l-1]) p = i,ans = 1;
    }
    // cerr<<p<<'\n';
    // cerr<<hs.get2(p,p+len-1)<<'\n';
    cout<<(hs.get2(p,p+len-1)*2+sum[n]-(sum[p+len-1]-sum[p-1]))%mod<<' ';
    cout<<ans<<'\n';
}
inline void solve(){
    cin>>n>>k>>(s+1);hs.init(s);
    Combination::init(n);fst = n;
    rep(i,1,n,1) if(s[i] == '1'){fst = i;break;}
    rep(i,1,n,1) sum[i] = sum[i - 1] + s[i] - '0';
    if(n == k) return cout<<sum[n]<<' '<<1<<'\n',void();
    if(fst >= k){
        cout<<hs.get2(fst,n)<<' ';
        int ans = 0;
        rep(i,k-1,fst-1,1) ans = (ans + C(fst-1,i)) % mod;
        cout<<ans<<'\n';
        return void();
    }
    solve1();
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    solve();
}

划分

打的\(O(n2^k\log n)\)的爆搜,然后由于忘记将调试改回去了挂了8pts。

不会

image

标签:inline,NOIP,int,rep,long,using,加赛,ll
From: https://www.cnblogs.com/hzoi-Cu/p/18530752

相关文章

  • noip模拟7
    新的阶乘考虑从这个式子下手,怎么更优秀的求得答案。\[\begin{aligned}f(x)&=x_1\times(x-1)^2\times(x-2)^3...2^{x-1}\times1^x\\&=\prod_{k=0}^{x-1}(x-k)^{k+1}\\&=x!\times\prod_{k=0}^{x-2}(x-1-k)^{k+1}\\&=x!\timesf(x-1)\\&=\prod_{k=1}......
  • NOIP2024加赛2
    NOIP2024加赛2题目来源:2023NOIPA层联测18\(T1\)HZTG5733.新的阶乘\(100pts\)预处理素数后直接对\(1\simn\)进行质因数分解因为有太多冗余枚举导致无法通过。考虑枚举最终形式。具体地,从质因数的角度入手,设当前枚举的质数为\(p\),暴力求出\(ip\)中\(p\)的指......
  • [2024.11.06]NOIP 模拟赛
    不会tarjan不会广义串并联图……赛时T1看上去很可做。看到中位数首先想到二分。在二分的背景下,问题转化为求当前最多能使多少个元素大于等于某个定值。我们不妨先让所有的元素都选择\(a\)值,然后相当于要选择一段连续的\(b\)替换一些\(a\),要求最后总和最大。所以可以新设......
  • CSP2024 前集训:NOIP2024加赛 1
    前言赛时本来rk3,赛后自己加hack卡自己于是成rk4了。因为这场是假做法大战,T1假贪心有\(92pts\);T2\(O(n^2m)\)能过(是因为数据里\(m\le10\));T3相当抽象,赛时我打的爆搜只加了一个剪枝能得\(70pts\),赛后发现无解的时候会跑满,于是提前判掉无解就过了甚至最优解\(30ms\)......
  • 多校A层冲刺NOIP2024模拟赛18
    多校A层冲刺NOIP2024模拟赛18\(T1\)A.选彩笔(rgb)\(100pts/100pts\)观察到\(0\ler,g,b\le255\)且答案具有单调性,故考虑二分答案。将\(r,g,b\)分别抽象成三维坐标下的\(x,y,z\)。设当前二分出的答案为\(mid\),由调整法分析可知若存在一个边长为\(mid\)的......
  • NOIP模拟(flandre、meirin、sakuya、scarlet) - 模拟赛总结
    flandre做得挺久的,大约做了\(\rm1h+\)。首先,选出来的序列一定是升序的,因为交换升序序列中的任意两个都不可能让「感觉效果」更高。然后来看选那些数组成这个序列。接下来是我赛时的想法:如果全为正数,那么自然正数全部都得选。需要考虑的是负数的情况。首先,选择一个负数不仅......
  • [61] (多校联训) A层冲刺NOIP2024模拟赛18
    无论从什么意义上都能称得上挂75分的一场A.选彩笔好题答案显然可以二分突然发现我好像专长二分答案钦定最大差值\(dx\),将所有物品以\((r,g,b)\)看成三维空间坐标内的点,原问题可以转化成问空间里一个边长为\(dx\)的立方体内是否有至少\(k\)个点考虑到值域不大,可......
  • 【某NOIP模拟赛T2 - 旅游】--线段树优化 DP 的魅力
    题意:数轴上在起点\(s\)和终点\(t\)间的整点中有\(n\)个关键点,第\(i\)个关键点位置为\(c_i\),可获得\(m_i\)的价值。你可以从起点开始,每次跳至多\(z\)个点(跨过中间的点),而每到达一个\(s\)以外的点需要支付\(a\)的代价,求走到终点的最大价值。\(0\les\lec_i\let......
  • noip模拟赛6
    A选彩笔(rgb)一眼转三维坐标系搞。但是最开始想歪了,以为要转曼哈顿距离,但是发现三维切比雪夫距离不支持转曼哈顿距离。补充一个知识点\(x\)维的曼哈顿距离支持转到\(2^{x-1}\)维的切比雪夫距离所以一维和二维可以直接转化,但是三维及以上就不行了。三维曼哈顿距离等同于某......
  • [DMY]2024 NOIP 模拟赛 Day 4
    不会暴搜不会差分约束不会三维DP不会根号分治不会卡常……赛时电脑没网,换了一台。T1看不懂题面,还以为是\(n-x\),然后有人给我说根据题目名称可以推断是\(n\%x\)。……[从现在开始到T2,我写完了,但是被人用手势删了,没保存,不想重新写了,所以就这样了]……T2赛后发现差分约束......