20250719 ACM轧钢记

被龙神带飞了%%%

高超的找到了签到,拿到了首A。

然后别的队切D了,我们也看D,也就黄题,但是由于我看错了题意导致整队意淫半个小时。

然后lzl去开M,切了。/bx

然后我看F,看会了,lzl写完了,发现题读错了,我太菜了

然后我对着I,A和G想了半天,每一个想出来的,一共切了3题,被拉爆了。

H - V 我 112.5

签到

void solve()
{
int a;
cin>>a;
LL now= 5000+50a;
cout<<fixed<<setprecision(3)<<"Vivo "<<1.
now/100<<endl;

}

D - 与或博弈

博弈,0-1轮就可以分出结果,记得关流

using ll=long long;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;
cin>>T;
while(T--){
ll a,b,x,y;
cin>>a>>b>>x>>y;

    if((a==x&&(b|y)==y)||(b==y&&(a&x)==x)){
        cout<<"Yes\n";
        continue;
    }
    cout<<"No\n";

}

}

M - 魔法使考核

倒着贪心,奇数使用-1,偶数比较一下/2的费用,和减-1的费用,会爆

include<bits/stdc++.h>

using namespace std;
using ll = long long;
using i128 = __int128_t;
typedef long long LL;
ostream &operator<<(std::ostream &os, i128 n) {
if (n == 0) {
return os << 0;
}
std::string s;
while (n > 0) {
s += char('0' + n % 10);
n /= 10;
}
std::reverse(s.begin(), s.end());
return os << s;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
ll n, x, y;
cin >> n >> x >> y;
vector a(n + 1);
for(int i = 1; i <= n; i++) cin >> a[i];
i128 ans = 0;
while(1){
i128 res = 0;
for(int i = 1; i <= n; i++){
if(a[i] % 2 == 1){
a[i]--;
ans += x;
}
a[i] /= 2;
res += a[i] * x;
}
ans += min(res, (i128)y);
bool f = 0;
for(int i = 1; i <= n; i++){
if(a[i]) f = 1;
}
if(f == 0) break;
}
cout << ans << "\n";
return 0;
}

G - 矩阵

构造,第一行

,然后接下来的每行都比前一行加一个比n大的质数。可以证明,第一行之间每个相邻数互质,加了一个质数之后,这一行之间相邻数依然会互质,相邻行之间也会互质。

void so(){
int n;cin>>n;
vector<vector>a(n+1,vector(n+1));
for(int i=1;i<=n;i++){
a[1][i]=i;
}
int tp=upper_bound(prime.begin(),prime.end(),a[1][n])-prime.begin();
int res=prime[tp];
for(int i=2;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][j]=a[i-1][j]+res;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<a[i][j]<<" ";
}
cout<<"\n";
}
}

K - 神之一手

概率
, ,分别表示存活到第i个回合,界外存在一格棋子,和0个棋子,那么用1减去

就是败北的概率,但是所求是当前轮败北概率,所以减去前缀败北概率(注意:大于80的时候,无论有没有放棋盒,棋子都会有概率掉出)

include<bits/stdc++.h>

using namespace std;
using ll= long long;
ll mod=1e9+7;
ll qmi(ll a,ll k){
ll res=1;
while(k){
if(k&1){
res=resa%mod;
}
k>>=1;
a=a
a%mod;
}
return res;
}
void solved()
{
ll p,q,r,P,Q,R;
cin>>p>>q>>r;
ll tp=qmi(1000,mod-2);
P=(1000-p)tp%mod,Q=(1000-q)tp%mod,R=(1000-r)tp%mod;
p=p
tp%mod,q=qtp%mod,r=rtp%mod;
int n;cin>>n;
vectora(n+1);
for(int i=1;i<=n;i++)cin>>a[i];
vector<array<ll,2>>dp(n+1);
dp[0][0]=1;
ll sum=0;
ll pre=0;
for(int i=1;i<=n;i++){
if(a[i]==0){
dp[i][0]=dp[i-1][0];
dp[i][1]=dp[i-1][1]R%mod;
ll ans=1-dp[i][0]-dp[i][1]-pre;
ans%=mod; ans+=mod; ans%=mod;
cout<<ans<<"\n";
pre+=ans;pre%=mod;
continue;
}
ll a1=80-sum,a2=sum+a[i]-80;
a1=min(80-sum,a[i]);
a2=max((ll)0,sum+a[i]-80);
if(sum>80)a1=0,a2=a[i];
dp[i][0]=dp[i-1][0]
qmi(P,a[i])%modqmi(Q,a2)%mod;
dp[i][1]+=dp[i-1][0]
qmi(P,max(a[i]-1,(ll)0))%moda1%modp%modqmi(Q,a2)%mod;
dp[i][1]+=dp[i-1][0]
qmi(P,max(a[i]-1,(ll)0))%moda2%modp%modqmi(Q,max(a2-1,(ll)0))%mod+dp[i-1][0]qmi(P,a[i])%moda2%modq%modqmi(Q,max(a2-1,(ll)0))%mod;
dp[i][1]%=mod;
dp[i][1]+=dp[i-1][1]
qmi(P,a[i])%modqmi(Q,a2)%modR%mod;
ll ans=1-dp[i][0]-dp[i][1]-pre;
ans%=mod; ans+=mod; ans%=mod;
cout<<ans<<"\n";
sum+=a[i];
pre+=ans;pre%=mod;

   }       

}

I - 真相

树形
,知道这个 的时间复杂度,就好写了,定义 数组, 不包含节点,包含节点 ,枚举

.

void solved()
{
ll n;cin>>n;
vectora(n+1);
vector<vector>e(n+1);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
vector<vector>dp(n+1,vector(n+1));
auto g=dp;
vectorsz(n+1);
auto dfs=[&](auto dfs,int u,int fa)->void{
dp[u][0]=1;
sz[u]=1;
int size=0;
for(auto son:e[u]){
if(sonfa)continue;
dfs(dfs,son,u);
vectortp(size+1+sz[son],0);
for(int i=0;i<=size;i++){
if(dp[u][i]
0)continue;
for(int j=0;j<=sz[son];j++){
if(g[son][j]==0)continue;
tp[i+j]+=dp[u][i]*g[son][j]%mod;
tp[i+j]%=mod;
}
}
size+=sz[son];
dp[u]=move(tp);
}
sz[u]+=size;
for(int i=0;i<=size;i++){
if(a[u]!=i){
g[u][i]=dp[u][i];
}
}
if(a[u]&&a[u]<=sz[u])g[u][a[u]]+=dp[u][a[u]-1],g[u][a[u]]%=mod;

};
dfs(dfs,1,0);
ll ans=0;
for(int i=0;i<=n;i++){
    ans+=g[1][i];
    ans%=mod;
}
cout<<ans<<"\n";

}

J - 画圈

为白边的数量, 通过黑黑边所构成的图的连通块的数量, 调的白边用来连接联通块,不会有贡献,剩下

条白边都会有贡献

void solved()
{
int n,m;
cin>>n>>m;
vectorfa(n+1);
for(int i=1;i<=n;i++)fa[i]=i;
auto find=[&](auto find,int x)->int{
if(fa[x]==x)return x;
fa[x]=find(find,fa[x]);
return fa[x];
};
int b=0,k=n;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
if(w){
int fu=find(find,u),fv=find(find,v);
if(fu!=fv)k--,fa[fu]=fv;
}
else b++;
}
cout<<b-(k-1)<<"\n";

}

A - 序列

请看
(bushi( ,播放

进行曲~~~

include <bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;

using u128 = unsigned __int128;
using i128 = __int128;

int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);

i64 x;
std::cin >> x;

std::vector<int> a;
auto dfs = [&](this auto &&self, i64 res, int n, int lst) -> void {
    if (res == x) {
        std::cout << "Yes\n";
        std::cout << n << "\n";
        std::vector<int> ans;
        for (int i = 0; i < a.size(); i++) {
            for (int j = 0; j < a[i]; j++) {
                ans.push_back(i + 1);
            }
        }
        for (int i = 0; i < n; i++) {
            std::cout << ans[i] << " \n"[i == n - 1];
        }
        std::exit(0);
    }
    
    for (int i = 1; i <= lst; i++) {
        i64 val = (res << i) + (1LL << (n + i)) - (1LL << n);
        if (val > x) {
            break;
        }
        a.push_back(i);
        self(val, n + i, i);
        a.pop_back();
    }
};

dfs(0, 0, 60);
std::cout << "No\n";

return 0;

}

E-Djangle 的数据结构

线段树
维护区间 ,对于一操作直接赋值,操作二如果查询的时候这个 mod ,那这个区间肯定不会发生任何变化,如果这个区间里的数都相同,直接对区间重新赋值为 , ,这里赋值

的过程其实数值是一直下降的,时间复杂度分析下来是够的(bushi,shui hui fen xi,这不得靠feel guess

include<bits/stdc++.h>

using namespace std;
using ll=long long;
using i64=long long;
using u64=unsigned long long;
template<class Info,class Tag>
struct LazySegementTree{//n+1
int n;
vector info;
vector tag;
LazySegementTree():n(0){}
LazySegementTree(int n_,Info v_=Info()){
init(n_,v_);
}
template
LazySegementTree(vector init_){
init(init_);
}
void init(int n_,Info v_=Info()){
init(vector(n_,v_));
}
template
void init(vector init_){
n=init_.size()-1;
info.assign((n+1)<<2,Info());
tag.assign((n+1)<<2,Tag());
function<void(int,int,int)> build=[&](int p,int l,int r){
if(lr){
info[p]=init_[l];
return;
}
int m=(l+r)/2;
build(p2,l,m);
build(p
2+1,m+1,r);
push_up(p);
};
build(1,1,n);
}
void push_up(int p){
info[p]=info[p2]+info[p2+1];
}
void apply(int p,const Tag &v) {
info[p].apply(v);
tag[p].apply(v);
}
void push_down(int p) {
apply(2p,tag[p]);
apply(2
p+1,tag[p]);
tag[p]=Tag();
}
void modify(int p,int l,int r,int x,const Info& u){
if(l
r){
info[p]=u;
return;
}
int m=(l+r)/2;
push_down(p);
if(x<=m) modify(p2,l,m,x,u);
else modify(p
2+1,m+1,r,x,u);
push_up(p);
}
void modify(int p,const Info& u){
modify(1,1,n,p,u);
}
Info query(int p,int l,int r,int st,int en){
if(l>en||r<st) return Info();
if(st<=l&&r<=en){
return info[p];
}
int m=(l+r)/2;
push_down(p);
Info sum;
if(st<=m) sum=sum+query(p2,l,m,st,en);
if(en>m) sum=sum+query(p
2+1,m+1,r,st,en);
return sum;
}
Info query(int l,int r){
return query(1,1,n,l,r);
}
void update(int p,int l,int r,int x,int y,const Tag &v){
if(l>y||r<x) return;
if(l>=x&&r<=y) {
apply(p,v);
return;
}
int mid=(l+r)/2;
push_down(p);
if(x<=mid) update(p2,l,mid,x,y,v);
if(y>mid) update(p
2+1,mid+1,r,x,y,v);
push_up(p);
}
void update(int l,int r,const Tag& v){
update(1,1,n,l,r,v);
}
template
int findfirst(int p,int l,int r,int x,int y,F pre){
if(l>y||r<x||!pre(info[p])){
return -1;
}
if(lr){
return l;
}
int mid=(l+r)/2;
push_down(p);
int res=findfirst(p*2,l,mid,x,y,pre);
if(res
-1){
return findfirst(p2+1,mid+1,r,x,y,pre);
}
return res;
}
template
int findfirst(int l,int r,F pre){
return findfirst(1,1,n,l,r,pre);
}
template
int findlast(int p,int l,int r,int x,int y,F pre){
if(l>y||r<x||!pre(info[p])){
return -1;
}
if(l==r){
return l;
}
int mid=(l+r)/2;
push_down(p);
int res=findlast(p
2+1,mid+1,r,x,y,pre);
if(res==-1){
return findlast(p*2,l,mid,x,y,pre);
}
return res;
}
template
int findlast(int l,int r,F pre){
return findlast(1,1,n,l,r,pre);
}
};
struct Tag{
ll v = 0;
void apply(Tag u){
if(u.v) v = u.v;
}
};
struct Info{
ll l = 0, sum = 0;
ll len = 0;
void apply(Tag u){
if(u.v){
l = u.v;
sum = len * u.v;
}
}
};
constexpr int inf = 1 << 30;
Info operator+(const Info &a, const Info &b){
Info c;
if(a.l > inf) c.l = a.l;
else if(b.l > inf) c.l = b.l;
else{
c.l = lcm(a.l, b.l);
}
c.len = a.len + b.len;
c.sum = a.sum + b.sum;
return c;
}
void solve(){
int n, q;
cin >> n >> q;
LazySegementTree<Info, Tag> seg(n + 1);
for(int i = 1; i <= n; i++){
int x;
cin >> x;
seg.modify(i, {x, x, 1});
}
while(q--){
int op;
cin >> op;
if(op == 0){
int l, r, v;
cin >> l >> r >> v;
seg.update(l, r, {v});
}else{
auto query = [&](auto query, int p, int l, int r, int L, int R, int v) -> ll{
if(l > R || r < l) return 0;
if(L <= l && r <= R){
if(v % seg.info[p].l == 0) return seg.info[p].sum;
if(seg.info[p].sum % (r - l + 1) == 0 && seg.info[p].sum / seg.info[p].l == r - l + 1){
int x = gcd(v, seg.info[p].l);
seg.info[p].l = x;
seg.info[p].sum = 1LL * x * seg.info[p].len;
seg.tag[p].v = x;
return seg.info[p].sum;
}
}
int m = (l + r) / 2;
seg.push_down(p);
ll ans = 0;
if(L <= m) ans += query(query, p * 2, l, m, L, R, v);
if(R > m) ans += query(query, p * 2 + 1, m + 1, r, L, R, v);
seg.push_up(p);
return ans;
};
int l, r, x;
cin >> l >> r >> x;
cout << query(query, 1, 1, n, l, r, x) << "\n";
}
}
}

posted @ 2025-07-20 20:12  Dreamers_Seve  阅读(15)  评论(0)    收藏  举报