Atcoder 229

\(D.\)Longest X

题意

给定一个长度为\(N\)的字符串\(S\),\(S\)中包含$\ .\ \(和\)\ X\ \(两种字符,现在你可以将其中\)K\(个\)\ .\ \(替换成\)X\(,问最后可能构成的连续的\)X$序列的长度最大是多少 \(1\le N,K \le 2\times 10^5\)

Sol

统计$\ . \ \(个数的前缀和为\)sum[i]\(表示下标为\)i\(之前含有多少个\)\ .\ \(,那么我们可以枚举左端点,然后右端点依次递增,然后用前缀和\)O(1)\(求出\)[l,r]\(之间有多少个\)\ .\ \(,判断是否小于\)K\(,让\)r\(一直递增直到大于\)K\(为止,很明显这里\)l,r\(都是单调递增的,因为假设\)[l,r]\(是用掉了所有\)K\(区间,那么说明\)[l,r]\(之间的\)\ .\ \(最少,\)X\(最多,当增加\)l\(时,\)X\(只可能变少,所以\)r$要让答案更优就必须增大。

#include <bits/stdc++.h>
#define ll long long
#define inf 0x7f7f7f7fll
#define fi first
#define se second
#define mod 998244353
#define pb push_back
using namespace std; template <typename T> void rd (T &x)
{
x=0;int f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') x=x*10+(s^48),s=getchar();
x*=f;
}
template <typename T> void chkMax(T &x, T y) { if (y > x) x = y; }
template <typename T> void chkMin(T &x, T y) { if (y < x) x = y; } const int N=2e5+10;
int cnt[N];
int main()
{
string s;
int k;
cin>>s;
rd(k);
int n=s.size();
for(int i=0;i<s.size();i++)
{
if(s[i]=='.') cnt[i+1]=cnt[i]+1;
else cnt[i+1]=cnt[i];
}
int ans=0; for(int l=0,r=0;l<n;l++)
{
while(r<n&&cnt[r+1]-cnt[l]<=k)
r=r+1;
ans=max(ans,r-l);
} cout<<ans<<'\n';
return 0;
}

\(E.\)Graph Destruction

题意

给定\(N\)个点\(M\)条边的无向图,按顺序删除\(1,2, ...,N\)这\(N\)个点,问每删除一个点当前图有多少个连通块。

\(1\le N,M\le 2\times 10^5\)

Sol

一开始我的想法是以拓扑序的方式统计每个点的出度,但只过了一半的数据,查了半天查不出来。

正解是用并查集维护连通块,但并查集支持的的连边统计连通块,但我们要进行的操作是删边,因此从\(N\)号节点开始加入节点连边,注意在一开连边的时候只从小的点向大的点连边,因为逆序处理,大的点不会影响它前面小的点,因为小的点会比它先被删除。

从\(N\)开始加,此时连通块个数+1,然后遍历它指向的大的点,如果他们不再一个连通块里,那么总的连通块数-1,最后总的连通块个数就是此时第\(i\)个点对应的答案。

#include <bits/stdc++.h>
#define ll long long
#define inf 0x7f7f7f7fll
#define fi first
#define se second
#define mod 998244353
#define pb push_back
using namespace std; template <typename T> void rd (T &x)
{
x=0;int f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') x=x*10+(s^48),s=getchar();
x*=f;
}
template <typename T> void chkMax(T &x, T y) { if (y > x) x = y; }
template <typename T> void chkMin(T &x, T y) { if (y < x) x = y; } const int N = 2e5+10, M = 2e5+10;
vector<int>E[N];
int f[N];
int find(int x)
{
return x==f[x]?x:f[x]=find(f[x]);
}
int main()
{ int n,m;
rd(n),rd(m);
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
int u,v;
if(u>v) swap(u,v);
rd(u),rd(v);
if(u>v) swap(u,v);
if(u==v) continue;
E[u].pb(v);
}
int ans=0;
vector<int>res={0};
for(int u=n;u>=2;u--)
{
ans++;
for(auto v:E[u])
{
int fu=find(u),fv=find(v);
if(fu!=fv)
{
f[fu]=fv;
ans--;
}
}
res.pb(ans);
}
reverse(res.begin(),res.end());
for(auto x:res) cout<<x<<'\n';
return 0;
}

\(F.\)Make Bipartite

题意

给定\(N+1\)给点,从\(0\)到\(N\)开始编号,每个点\(i\)(\(1\le i\le N\))向\(0\)号点连边权为\(A_i\)的边,然后\(i\)号点向\(i+1\)号点连边权为\(B_i\)的边\((N+1=1)\),问如果把这个图变成二分图,最小需要删除的边的权重和是多少

\(1\le N\le 2\times10^5\) \(1\le A_i,B_i\le 10^9\)

Sol

进行二分染色,不妨固定\(0\)号点为白色(用\(0/1\)表示白色/黑色)

定义\(dp[i][j][k]\)表示当前染到了第\(i\)号点,当前\(i\)号点染色为\(j\),\(1\)号点染色为\(k\)的最小边权和

初始\(dp[1][0][0]=A_i\)表示\(1\)号点染色为白色,说明\(1\)号点和\(0\)号点在一个点集里,那么它们之间就不能有边,于是要删去的边权为\(A_i\)

\(dp[1][1][1]=0\)表示\(1\)号点和\(0\)号点不在一个点集里,说明不需要删边,所以为\(0\)

转移:\(dp[i][j][k]=min(dp[i][j][k],dp[i-1][prej][k]+(j==0?A_i:0)+(prej==j?B_{i-1}:0))\)

第\(i\)个点由第\(i-1\)个点转移而来,如果第\(i\)个点染色为\(0\),说明\(i\)号点和\(0\)在一个集合里,那么就要断开和\(0\)所连的边;

如果第\(i\)个染色\(j\)和第\(i-1\)个点的染色\(prej\)一样,说明\(i\)号点和\(i+1\)号点在一个点集里,要断开它们之间的边,答案要加上\(B_{i-1}\)

最后只需要检查一遍染完\(N\)点的所有集合就可以了

#include <bits/stdc++.h>
#define ll long long
#define inf 1e18
#define fi first
#define se second
#define mod 998244353
#define pb push_back
using namespace std; template <typename T> void rd (T &x)
{
x=0;int f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') x=x*10+(s^48),s=getchar();
x*=f;
}
template <typename T> void chkMax(T &x, T y) { if (y > x) x = y; }
template <typename T> void chkMin(T &x, T y) { if (y < x) x = y; }
const int N=2e5+10;
int A[N],B[N];
ll dp[N][2][2];
int main()
{ int n;
rd(n);
for(int i=1;i<=n;i++) rd(A[i]);
for(int i=1;i<=n;i++) rd(B[i]); for(int i=1;i<=n;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
dp[i][j][k]=1e18;
dp[1][0][0]=A[1];
dp[1][1][1]=0;
for(int i=2;i<=n;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
for(int prej=0;prej<2;prej++)
dp[i][j][k]=min(dp[i][j][k],dp[i-1][prej][k]+(j==0?A[i]:0)+(j==prej?B[i-1]:0));
ll ans=1e18;
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
ans=min(ans,dp[n][j][k]+(j==k?B[n]:0));
cout<<ans<<'\n';
return 0; }

\(G.\) **Longest Y **

题意

给定一个长度为\(N\)的字符串\(S\),\(S\)中包含$\ .\ \(和\)\ Y\ \(两种字符,现在你可以进行\)K\(次操作,每次操作可以交换相邻的两个字符,问最后可能构成的连续的\)Y$序列的长度最大是多少 \(2\le N,K \le 2\times 10^5\) \(1\le K\le 0^{12}\)

Sol

将所有\(Y\)的位置记录到一个数组\(B\)中

令\(B_i=B_i-i\),那么将\(B_i+1\)对应于将原序列的位置和右边的字符交换,将\(B_i-1\)对应于将原序列的位置和左边的字符交换。

现在问题就是问进行\(K\)次加减运算最多可以令多少个\(B_i\)相同。

考虑吧长度为\(Len\)的区间变为一样的数最少需要几次操作,这是一个经典的问题

\(f(Len)=\sum_{i=t}^{min(Size(B),t+Len-1)}|B_t-x|\),其中\(x\)为这个区间的中位数

因此可以枚举二分区间长度即可。如果操作次数小于\(k\),说明区间长度还可以更大,反之区间长度就要变小

#include <bits/stdc++.h>
#define ll long long
#define inf 0x7f7f7f7fll
#define fi first
#define se second
#define mod 998244353
#define pb push_back
using namespace std; template <typename T> void rd (T &x)
{
x=0;int f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();}
while(s>='0'&&s<='9') x=x*10+(s^48),s=getchar();
x*=f;
}
template <typename T> void chkMax(T &x, T y) { if (y > x) x = y; }
template <typename T> void chkMin(T &x, T y) { if (y < x) x = y; }
const int N=2e5+10;
int cnt;
ll k;
ll B[N],sum[N];
bool check(int len)
{ for(int l=1;l+len-1<=cnt;l++)
{
ll s=0;
int r=min(l+len-1,cnt);
int mid=l+r>>1;
s+=(mid-l+1ll)*B[mid]-(sum[mid]-sum[l-1]);
s+=(sum[r]-sum[mid-1])-(r-mid+1ll)*B[mid];
if(s<=k)return true;
}
return false;
}
int main()
{
string s;
cin>>s;
rd(k);
int n=s.size();
for(int i=0;i<n;i++)
if(s[i]=='Y') B[++cnt]=i+1;
for(int i=1;i<=cnt;i++)
B[i]-=i;
sort(B+1,B+1+cnt);
for(int i=1;i<=cnt;i++)
sum[i]=sum[i-1]+B[i]; int l=0,r=n;
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
cout<<l<<'\n';
return 0; }

Atcoder 229的更多相关文章

  1. Android Weekly Notes Issue #229

    Android Weekly Issue #229 October 30th, 2016 Android Weekly Issue #229 Android Weekly笔记, 本期内容包括: 性能库 ...

  2. ftp 229

    在sels10机器上登入ftp输入用户名和密码之后再ls发现出现如下问题Entering Extended Passive Mode ftp> ls229 Entering Extended P ...

  3. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  4. AtCoder Grand Contest 001 C Shorten Diameter 树的直径知识

    链接:http://agc001.contest.atcoder.jp/tasks/agc001_c 题解(官方): We use the following well-known fact abou ...

  5. Request Connection: Remote Server @ 192.229.145.200:80

    录制Loadrunner脚本时,提示: Request Connection: Remote Server @ 192.229.145.200:80   NOT INTERCEPTED!(REASON ...

  6. AtCoder Regular Contest 082

    我都出了F了……结果并没有出E……atcoder让我差4分上橙是啥意思啊…… C - Together 题意:把每个数加1或减1或不变求最大众数. #include<cstdio> #in ...

  7. AtCoder Regular Contest 069 D

    D - Menagerie Time limit : 2sec / Memory limit : 256MB Score : 500 points Problem Statement Snuke, w ...

  8. AtCoder Regular Contest 076

    在湖蓝跟衡水大佬们打的第二场atcoder,不知不觉一星期都过去了. 任意门 C - Reconciled? 题意:n只猫,m只狗排队,猫与猫之间,狗与狗之间是不同的,同种动物不能相邻排,问有多少种方 ...

  9. AtCoder Grand Contest 016

    在雅礼和衡水的dalao们打了一场atcoder 然而窝好菜啊…… A - Shrinking 题意:定义一次操作为将长度为n的字符串变成长度n-1的字符串,且变化后第i个字母为变化前第i 或 i+1 ...

随机推荐

  1. zabbix-server3.4安装

    1.安装yum源 rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-1.el7.noarch.rp ...

  2. Spring系列7:`autowire`自动装配怎么玩

    回顾 前几篇我们介绍各种依赖依赖注入,都是显式指定的,配置明确但同时也有些繁杂和重复."很多发明的出发点,都是为了偷懒,懒人是推动社会进步的原动力".Spring 提供了自动注入依 ...

  3. QA(测试) 工作准则建议

    身为一个专业的 QA 当然需要有自己的测试原则,这些测试原则不仅可以帮助我们提高产品质量,对外还能体现出我们的专业性,从而让合作方后续还有意愿和我们合作. 1 测试前 1.1 需求评审 必须参与,有问 ...

  4. 如何使用 C++ 和 OpenCV 实现截屏

    前言 实现屏幕截屏需要用到 Windows API,所以需要包括 Windows.h 头文件.同时我们想要对截图做进一步的处理,就需要用到 OpenCV.关于 OpenCV 的安装与编译可以参见 &l ...

  5. 洛谷 8 月月赛 & 「PMOI」Round · 04

    T1 T166167 「PMOI-4」人赢 题目大意 给一个数列的前两项分别为\(n\)和\(m\) 当\(i\geq3\)时\(a_i = a_{i-1}*a_{i-2}\)的个位 给定\(n\), ...

  6. 记项目中ES6+gulp+angularjs里的问题

    AngualrJs中可用来注入的有三种类型,service.factory.provider,这三种写法不样,用法也都不一样.其中,service只实例化一次,其实就是单例模式的思想.无论我们在什么地 ...

  7. CABasicAnimation基础核心动画

    核心动画之作用在层上面.     动画的本质是改图层的某一个属性.     CABasicAnimation *anim = [CABasicAnimation animation];     图层有 ...

  8. unittest基础篇1

    转自http://blog.csdn.net/huilan_same/article/details/52944782 unittest是xUnit系列框架中的一员,如果你了解xUnit的其他成员,那 ...

  9. 干工第一天,这个api超时优化把我干趴下了!

    近日我司进行云服务商更换,恰逢由我负责新上线的三方调用 api 维护管理,在将服务由阿里云部署到腾讯云过程中,我们压测发现在腾讯云调用京东接口时 TP999 抖动十分剧烈,尽管业务层有重试操作但是超时 ...

  10. treevalue——Master Nested Data Like Tensor

    首先,请和我一起高呼--"treevalue--通用树形结构建模工具 + 极简树形结构编程模型". 咳咳,好久没更新了,这一次是真的好久不见,甚是想念.在之前的三期中,关于 tre ...