当前位置: 首页 > news >正文

24ICPC成都站补题

A 构造

void solve(){string s;cin>>s;int n=s.size();if(n<5)rno;//#define rno return cout<<"No"<<endl,void()s=' '+s;int hd=0,fg=0;vector<int>t,h;vector<pii>ans;reforr(i,1,n){if(fg==0){hd+=(s[i]=='>');//hd匹配头上的>>>if(s[i]=='-'){if(hd<3)rno;fg=1;}}else if(s[i]=='>')t.push_back(i);}//s[1]一定要是>  否则会有->-->>>的不合法情况if(s[1]=='-'||fg==0||t.size()==0){rno;//#define rno return cout<<"No"<<endl,void()}int bg=n-hd+3;reforr(i,bg,n)h.push_back(i);//头顶从大到小sort(t.begin(),t.end());//尾巴从小到大if(h.size()>t.size())swap(h,t);int sz=h.size(),pid=0;for(auto i:t){ans.push_back({min(i,h[pid]),max(i,h[pid])});if(pid+1<sz)pid++;}cout<<"Yes "<<ans.size()<<endl;for(auto x:ans){cout<<x.fir<<' '<<x.sec-x.fir+1<<endl;}
}

G 位运算 思维

只有三种运算x&y x^y x|y
每一位上01状态不同会有不同的结果,所以把xy的每一位组合在一起看结果能得到什么样的数

void solve(){int n;cin>>n;set<int>s;vector<int>a(n+1);forr(i,1,n)cin>>a[i];//废案 一开始想到了暴力bfs// forr(i,2,n-1){// 	s.insert(a[i+1]&a[i]);// 	s.insert(a[i+1]|a[i]);// 	s.insert(a[i+1]^a[i]);// }s.insert(0);forr(i,1,n-1){//b11结果是x&y的该位结果  b10+b01是^ b10+b11+b01是|int b11,b10,b01;b11=b01=b10=0;//计算每一位情况reforr(j,0,31){int bnow=a[i]&(1<<j),bnxt=a[i+1]&(1<<j);if(bnow&&bnxt)b11|=bnow;else if(bnow)b10|=bnow;else if(bnxt)b01|=bnxt;}//x=now  y=nxt//b10:x^y&x->(b10+b01-b01)  b01:x^y&y//b10+b11:x  b01+b11:yvector<int>tp={b11,b10+b01,b11+b01+b10,b10,b01,b10+b11,b01+b11};for(auto t:tp)s.insert(t);}cout<<s.size()<<endl;
}

I 线段树 gcd

把数组分成长度为k的等长的非递减段(最后一段可以<=k),最后求合法k的个数
最大的k就是每个非递减段长度的gcd

  • 这里可以直接用分段处的下标 因为gcd(a,b-a)=gcd(a,b)

如 2 3 |1 4 5 7 | 8 9,k=2
分段下标i=2 6 8

每个等长非递减段又可以分,分解成k的因数长
有多个询问,使用线段树优化

const int N=2e5+4;
struct node
{  //区间   值int l,r,val;
};
struct segmentr{node tr[N<<2];void build(int pos,int l,int r){tr[pos]={l,r,0};if(l!=r){int mid=(l+r)>>1;build(pos<<1,l,mid);build(pos<<1|1,mid+1,r); }}void pushup(int pos){tr[pos].val=__gcd(tr[pos<<1].val,tr[pos<<1|1].val);//更新大区间的gcd}void modify(int pos,int aim,int val){if(tr[pos].l==tr[pos].r){tr[pos].val=val;return;}int mid=(tr[pos].l+tr[pos].r)>>1;if(mid>=aim)modify(pos<<1,aim,val);else modify(pos<<1|1,aim,val);pushup(pos);}
}t;
int cnt[N];//因数个数
//直接对分界点位置i进行gcd 因为gcd(a,b,c)=gcd(a,b-a,c-b) 线性组合后gcd不变
void solve(){int n,q;cin>>n>>q;t.build(1,1,n);vector<int>a(n+2);forr(i,1,n){cin>>a[i];}a[n+1]=0;forr(i,1,n-1){//最后一个点不必加进去 因为长度不一定是kif(a[i]>a[i+1]){t.modify(1,i,i);//记录递增段最后的一个点 递减分界点}else t.modify(1,i,0);}int ans=t.tr[1].val;//所有断点下标的gcdif(ans==0)cout<<n<<endl;//a全为0 最长段是nelse cout<<cnt[ans]<<endl;//注意最后要输出合规长度的数量forr(i,1,q){int p,v;cin>>p>>v;a[p]=v;if(p>1&&a[p-1]>a[p])t.modify(1,p-1,p-1);else t.modify(1,p-1,0);if(p<n&&a[p+1]<a[p])t.modify(1,p,p);else t.modify(1,p,0);int ans=t.tr[1].val;if(ans==0)cout<<n<<endl;else cout<<cnt[ans]<<endl;}
}
signed main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);forr(i,1,N-3){for(int j=1;i*j<=N-3;j++)cnt[i*j]++;}int _=1;cin>>_;while (_--){solve();}return 0;
}

B dp计情况数 三位前缀和优化

const int N=304,mod=1e9+7;
//a b c数量有制约关系 可以优化一维c
int nd[N],dp[N][N][N][4];//dp[i][j][k][p] i位置 用j个a k个b 有多少情况
int sum[N][N][N];
void solve(){int n,q;cin>>n>>q;string s;cin>>s;s=' '+s;forr(i,1,n){nd[i]=nd[i-1]+(s[i]=='?');//nd记录i位置之前需要多少}if(s[1]=='?')dp[1][1][0][0]=dp[1][0][1][1]=dp[1][0][0][2]=1;else dp[1][0][0][s[1]-'a']=1;//dp计算情况数forr(i,2,n){forr(a,0,nd[i]){for(int b=0;b+a<=nd[i];b++){int c=nd[i]-a-b;forr(p,0,2){if(s[i]=='?'){if(a&&p!=0)(dp[i][a][b][0]+=dp[i-1][a-1][b][p])%=mod;if(b&&p!=1)(dp[i][a][b][1]+=dp[i-1][a][b-1][p])%=mod;if(c&&p!=2)(dp[i][a][b][2]+=dp[i-1][a][b][p])%=mod;}else{if(p==s[i]-'a')continue;(dp[i][a][b][s[i]-'a']+=dp[i-1][a][b][p])%=mod;}}}}}//sum求三维前缀和 对之后a b c的询问优化forr(a,0,300){forr(b,0,300){forr(c,max(nd[n]-a-b,0ll),300){if(a+b+c<=nd[n])(sum[a][b][c]+=((dp[n][a][b][0]+dp[n][a][b][1])%mod+dp[n][a][b][2]))%=mod;if(a)(sum[a][b][c]+=sum[a-1][b][c])%=mod;if(b)(sum[a][b][c]+=sum[a][b-1][c])%=mod;if(c)(sum[a][b][c]+=sum[a][b][c-1])%=mod;if(b&&c)(sum[a][b][c]+=mod-sum[a][b-1][c-1])%=mod;if(a&&c)(sum[a][b][c]+=mod-sum[a-1][b][c-1])%=mod;if(a&&b)(sum[a][b][c]+=mod-sum[a-1][b-1][c])%=mod;if(a&&b&&c)(sum[a][b][c]+=sum[a-1][b-1][c-1])%=mod;}}}/*三维前缀和S(x, y, z) = a(x, y, z)+ S(x, y, z-1) + S(x, y-1, z) + S(x-1, y, z)- S(x, y-1, z-1) - S(x-1, y, z-1) - S(x-1, y-1, z)+ S(x-1, y-1, z-1)*/forr(i,1,q){int a,b,c;cin>>a>>b>>c;cout<<sum[a][b][c]<<endl;}
}
http://www.dtcms.com/a/445985.html

相关文章:

  • DAY 41 简单CNN-2025.10.5
  • 网站建设的图片怎么加水印剪辑软件
  • 【c++】面 向 对 象 与 抽 象 数 据 类 型
  • 国内网站设计制作泰安招聘信息最新招聘2022
  • 第十二章:代理模式 - 访问控制的守护大师
  • 用wordpress建立学校网站网络营销软文案例
  • C++11线程相关
  • 住房和城乡建设统计网站网站开发公司需要招聘哪些人
  • 小土堆pytorch
  • 环保网站 中企动力建设专业的网站建设网络
  • 触摸未来2025.10.05:悟神经网络符号之伤,拥抱声音的宇宙
  • 大连鼎信网站建设wordpress简历模板
  • 关于运放的自激振荡和相位裕度
  • Edu164
  • 高端网站建设的网站四川城乡建设网站
  • 滑块(Slider)的原理与应用
  • 网站条形码如何做phpmysql网站开发技术项目式教程
  • 【LeetCode热题100】No.128——最长连续序列
  • 2025-10-04 HETAO CSP-S复赛集训营模拟赛-003 Ⅰ
  • 上海知名的网站建设公司网络优化是做啥的
  • 解码排序算法
  • 站长平台百度百度百科优化
  • 归一化分析3
  • Vue中的data为什么是函数?
  • Odoo 19 Studio 新功能实战培训
  • 手机网站qq代码市场营销的十大理论
  • 能源经济大赛选题推荐:新能源汽车试点城市政策对能源消耗的负面影响——基于技术替代效应的视角
  • 做付费软件网站怎么做广州有什么好玩的地方景点推荐
  • 【数据结构】考研算法精讲:分块查找的深度剖析 | 从“块内无序、块间有序”思想到ASL性能最优解
  • Go语言:用Go操作SQLite详解