wxy 3.26 #12
v>
A
签到题
考虑全面,是否需要和0进行比较
G
思维题
aa
bb 这样的直接交换第一个a和第二个b就可以了
ab
ba那么先通过一次交换把他变成上面哪一种情况,再交换即可
F
还是写的太慢了,卡了好久。。。其实有更简便的方法的
就是计算前面有多少是可以到该点是符合要求的,每遇到一次0就更新一次。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=2e5+100;
int a[MAXN];
int main()
{
int n; scanf("%d",&n);
LL ansn=0,ansz=0,ansp=0;
LL pren=0,prez=0,prep=1,now=1;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
if(a[i]==0){
prep=1,pren=0,now=1;
ansz+=1ll*(i-prez)*(n-i+1);
prez=i;
continue;
}
if(a[i]<0) now*=-1;
if(a[i]>0) now*=1;
if(now>0) ansp+=prep,ansn+=pren,prep++;
else ansp+=pren,ansn+=prep,pren++;
}
printf("%lld %lld %lld\n",ansn,ansz,ansp);
return 0;
}L
应为n只有1000,而且楼层只有两层,直接n^2暴力就好了
/补题/
B
类似于求树的重心的做法。 再次理解求树的重心:dfs回溯。 对任意一个点 dfs求他的每个子树的大
小,然后和父亲相连的那个树就是n-siz[x],,即可求出当前的max_part,然后用全局变量更新重心即
可。每次dfs都能求出搜到的那个节点为更的max_part相当于每个节点只被搜了一遍 事件复杂度O(n)。
回到这道题目上,解法是dfs每个子树,和父亲相连的那个子树的染色点即为 k -sz[x] ,符合条件发放入
vector即可
# include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+100;
int f[MAXN];
struct Edge{
int to,next;
}edge[MAXN<<1];
int head[MAXN];
int tot=0,n,k;
void add(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int r[MAXN],vis[MAXN];
vector<int> ans;
void dfs(int x)
{
vis[x]=1; r[x]=f[x];
int flag=1;
for(int i=head[x];~i;i=edge[i].next){
Edge e=edge[i];
if(vis[e.to]) continue;
dfs(e.to);
if(!r[e.to]) flag=0;
r[x]+=r[e.to];
}
if(!f[x]&&flag&&(x==1||k>r[x])) ans.push_back(x);
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++){
int a; scanf("%d",&a);
f[a]=1;
}
for(int i=1;i<n;i++){
int u,v; scanf("%d%d",&u,&v);
add(u,v); add(v,u);D
没来得及看,被F卡了好久。。。QAQ, 赛后看一下是博弈。 给你一个少了一些的数字的数字串,若前
一半和等于后一半和那么就是开心的串。分类讨论:1.如果前面的位数等于后面的位数:如果前面的和
等于后面的和,那么决策为:前一个人放什么后一个人放什么就可以;如果前面的和不等于后面的和,
那么前一个人先放,再后一个人放什么前一个人放什么,加入的还是一样的,那么肯定不相等。2.如果
前面的位数比后面的大:如果前面的和大于等于后面的和,那么前面的人在前面的那边放9,然后后面
的放什么相对的放什么即可,那么放的前面一定比前面大;如果前面的和小于后面的和只有差为9的位
数/2倍的时候才能够采取策略前面的放什么后面的相应放什么,使得先相等,然后再在位数多的那一边
前面的放几,后面的放9-前面的数;其他情况都不可以,先手一定有办法破坏后手的策略。3.如果前面
的位数比后面的小:和2类似
}
dfs(1);
sort(ans.begin(),ans.end());
int len=ans.size();
printf("%d\n",len);
for(int i=0;i<len;++i){
printf("%d ",ans[i]);
}
printf("\n");
return 0;
}
# include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+100;
char s[MAXN];
int main()
{
int flag=0;
int n; scanf("%d",&n);
scanf("%s",s+1);
int pre=0,nex=0,psum=0,nsum=0;
for(int i=1;i<=n/2;i++){
if(s[i]=='?') pre++;
else psum+=s[i]-'0';
}
for(int i=n/2+1;i<=n;i++){
if(s[i]=='?') nex++;
else nsum+=s[i]-'0';
}
if(pre==nex){
if(psum==nsum) flag=0;
else flag=1;
}else if(pre>nex){
if(psum>=nsum) flag=1;
else{
int ws=pre-nex;
int cc=nsum-psum;
if(cc!=9*ws/2) flag=1;
else flag=0;
}
}else if(pre<nex){H
求最长的等差序列的长度
DP[ i ] [ j ]表示从i位置开始,差为a[j]-a[i]的最长的等差序列的长度,DP[ i ] [ k]= DP[ j ] [ k] +1 表示从i
开始差为k的等差序列可以由在他后面的位置j开始的差为k的序列转移得到,当前k=a[j]-a[i] a[id]-
a[j]=k=a[j]-a[i] a[id]=a[j]+k id可以lower_bound查找时间复杂度 n^2*logn
I
if(psum<=nsum) flag=1;
else{
int ws=pre-nex;
int cc=nsum-psum;
if(cc!=9*ws/2) flag=1;
else flag=0;
}
}
if(flag) printf("Monocarp\n");
else printf("Bicarp\n");
return 0;
}
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=3e3+100;
LL a[MAXN];
int dp[MAXN][MAXN];
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
}
int ans=2;
for(int i=n;i;--i){
for(int j=i+1;j<=n;++j){
LL k=a[j]-a[i];
int id=lower_bound(a+1,a+n+1,a[j]+k)-(a);
if(a[id]!=a[j]+k){
dp[i][j]=2;
continue;
}
dp[i][j]=max(dp[i][j],max(2,dp[j][id]+1));
ans=max(ans,dp[i][j]);
}
}
printf("%d",ans);
return 0;
}满足朋友的个数期望=每个朋友被满足的概率之和,容斥一下,应为容斥原理满足结合性所以一个个加
上去就可以了。
J
模拟题,要读懂题意,仔细题目条件,还有循环倒叙的时候要写明条件i>0尽量不用i作为结束条件如果i
小于0的话是停不下来的。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=2e5+100;
const LL mod=998244353;
LL a[MAXN];
LL quick_pow(LL a,LL b)
{
LL ret=1;
while(b)
{
if(b&1) ret=ret*a%mod;
a=a*a%mod;
b>>=1;
}
return ret;
}
map<LL,int> mp;
LL p[MAXN];
int main()
{
int n; LL P,Q; scanf("%d%lld%lld",&n,&P,&Q);
LL R=1ll*1e6-P-Q;
P=P*quick_pow(1e6,mod-2)%mod;
Q=Q*quick_pow(1e6,mod-2)%mod;
R=R*quick_pow(1e6,mod-2)%mod;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
mp[a[i]]=i;
}
for(int i=1;i<=n;i++){
int x=mp[a[i]],y=mp[a[i]+1],z=mp[a[i]-1];
p[x]=(p[x]+R-R*p[x]%mod+mod)%mod;
if(y) p[y]=(p[y]+Q-Q*p[y]%mod+mod)%mod;
if(z) p[z]=(p[z]+P-P*p[z]%mod+mod)%mod;
}
LL ans=0;
for(int i=1;i<=n;i++){
ans=(ans+p[i])%mod;
}
printf("%lld\n",ans);
return 0;
}# include <bits/stdc++.h>
using namespace std;
int main()
{
int n; scanf("%d",&n);
int k=n*n*3/4;
printf("%d\n",k);
for(int i=n-1;i>0;i-=2){
for(int j=1;j<=n;j+=2){
printf("1 %d %d 1\n",i,j);
printf("1 %d %d 1\n",i+1,j+1);
printf("2 %d %d 2\n",i,j);
}
}
return 0;
}
其实还是有很多题目是可以做的,只要前面不被一些简单的题目卡住,稳扎稳打。还有不要被过题人数
限制了,有可能少数人过的题目也是能过做的,不一定要先做过的人多的,放平心态。
向wjmzbmr学习,acm本就是逆天而行。
浙公网安备 33010602011771号