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
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
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=aa%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=ptp%mod,q=qtp%mod,r=rtp%mod;
int n;cin>>n;
vector
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;
vector
vector<vector
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
auto g=dp;
vector
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);
vector
for(int i=0;i<=size;i++){
if(dp[u][i]
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;
vector
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
vector
LazySegementTree():n(0){}
LazySegementTree(int n_,Info v_=Info()){
init(n_,v_);
}
template
LazySegementTree(vector
init(init_);
}
void init(int n_,Info v_=Info()){
init(vector(n_,v_));
}
template
void init(vector
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(p2+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(2p+1,tag[p]);
tag[p]=Tag();
}
void modify(int p,int l,int r,int x,const Info& u){
if(lr){
info[p]=u;
return;
}
int m=(l+r)/2;
push_down(p);
if(x<=m) modify(p2,l,m,x,u);
else modify(p2+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(p2+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(p2+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
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";
}
}
}
浙公网安备 33010602011771号