Educational Codeforces Round 58 Div. 2 自闭记

时间:2023-03-09 19:20:02
Educational Codeforces Round 58 Div. 2 自闭记

  明明多个几秒就能场上AK了。自闭。

  A:签到。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,l,r,d;
signed main()
{
/*#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif*/
T=read();
while (T--)
{
l=read(),r=read(),d=read();
if (d<l) cout<<d<<endl;
else cout<<1ll*(r/d+)*d<<endl;
}
return ;
//NOTICE LONG LONG!!!!!
}

  B:签到。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n;
char s[N];
signed main()
{
/*#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif*/
scanf("%s",s+);n=strlen(s+);
bool flag=;int x=n+,y=;
for (int i=;i<=n;i++)
{
if (s[i]=='[') flag=;
if (s[i]==':') if (flag) {x=i;break;}
}
flag=;
for (int i=n;i>=;i--)
{
if (s[i]==']') flag=;
if (s[i]==':') if (flag) {y=i;break;}
}
if (x>=y) cout<<-;
else
{
int ans=;
for (int i=x+;i<y;i++)
if (s[i]=='|') ans++;
cout<<ans;
}
return ;
//NOTICE LONG LONG!!!!!
}

  C:wa了无数发。按左端点排序后找一个连续且和其他线段不相交的线段集即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,ans[N];
struct data
{
int l,r,i;
bool operator <(const data&a) const
{
return l<a.l;
}
}a[N];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
T=read();
while (T--)
{
n=read();
for (int i=;i<=n;i++) a[i].l=read(),a[i].r=read(),a[i].i=i;
sort(a+,a+n+);
bool flag=;a[n+].l=;
int t=,x=a[].r;
while (t<n&&a[t+].l<=x) t++,x=max(x,a[t].r);
if (t==n) cout<<-<<endl;
else
{
for (int i=;i<=t;i++) ans[a[i].i]=;
for (int i=t+;i<=n;i++) ans[a[i].i]=;
for (int i=;i<=n;i++) printf("%d ",ans[i]);
cout<<endl;
}
}
return ;
//NOTICE LONG LONG!!!!!
}

  E:这才是真签到吧?wa了一发自闭啊?

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 500010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int m,u,v;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
const char LL[]="%I64d\n";
#endif
m=read();
while (m--)
{
char c=getchar();while (c!='+'&&c!='?') c=getchar();
int x=read(),y=read();if (x>y) swap(x,y);
if (c=='+')
{
u=max(u,x),v=max(y,v);
}
else
{
if (x>=u&&y>=v) printf("YES\n");
else printf("NO\n");
}
}
return ;
//NOTICE LONG LONG!!!!!
}

  D:如果路径经过某点,最后所得的路径gcd显然是该点某些质因子的倍数。对此dp即可。一发wa on 3,3可是样例啊?自闭了啊?

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,a[N],p[N],f[N][],prime[N][],t,ans;
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs(int k,int from)
{
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=from)
{
dfs(edge[i].to,k);
for (int x=;x<=prime[edge[i].to][];x++)
for (int y=;y<=prime[k][];y++)
if (prime[edge[i].to][x]==prime[k][y])
{
ans=max(ans,f[k][y]+f[edge[i].to][x]+);
f[k][y]=max(f[k][y],f[edge[i].to][x]+);
}
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read();
for (int i=;i<=n;i++) a[i]=read();
bool flag=;
for (int i=;i<=n;i++) if (a[i]!=) flag=;
if (flag) {cout<<;return ;}
for (int i=;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
for (int i=;i<=n;i++)
{
for (int j=;j*j<=a[i];j++)
if (a[i]%j==)
{
prime[i][++prime[i][]]=j;
while (a[i]%j==) a[i]/=j;
}
if (a[i]>) prime[i][++prime[i][]]=a[i];
}
dfs(,);
cout<<ans+;
return ;
//NOTICE LONG LONG!!!!!
}

  G:一眼线性基,然后就往别的方面想了。自闭了半天直接乱搞求个前缀异或和搞了个线性基上去就pp了。冷静了半天正确性何在。事实上划分序列相当于选出一些前缀异或和,这是一个裸到不行的线性基。注意虽然最后一个前缀和应该是必须选的,但是不考虑也不会造成什么影响(吧)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,a[N],base[],ans;
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read();
for (int i=;i<=n;i++) a[i]=a[i-]^read();
if (a[n]==) {cout<<-;return ;}
for (int i=;i<=n;i++)
for (int j=;~j;j--)
if (a[i]&(<<j))
{
if (base[j]) a[i]^=base[j];
else {base[j]=a[i],ans++;break;}
}
cout<<ans;
return ;
//NOTICE LONG LONG!!!!!
}

  F:随便都知道是二分答案。但是nmlog显然有些吃力。考虑random_shuffle一发,每次记录当前需要的最大容量,考虑下一辆卡车时先判断当前容量是否能满足其需求,如果不行再二分一下。这样复杂度大约是nm+nlogmlogV,因为只需要对所需容量的单调栈中的卡车进行二分,而排列又是随机的。复杂度证明似乎在一篇cfblog里看到过。(突然发现整个idea都在这篇blog里https://codeforces.com/blog/entry/62602)一开始又没注意到要开long long,交一发in queue了半天,然后wa on 3,结果改了一发又没改全,交一发再次in queue了半天,接着wa on 3。然后就只剩20s了,手速不行,就,自闭了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
#define ll long long
#define N 410
#define M 250010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,a[N];
ll ans;
struct data{int s,f,c,r;
}b[M];
bool check(ll k,int i)
{
ll cur=k;int cnt=;
for (int j=b[i].s;j<b[i].f;j++)
{
if (cur>=1ll*b[i].c*(a[j+]-a[j])) cur-=1ll*b[i].c*(a[j+]-a[j]);
else
{
cur=k,cnt++;
if (cur>=1ll*b[i].c*(a[j+]-a[j])) cur-=1ll*b[i].c*(a[j+]-a[j]);
else return ;
}
if (cnt>b[i].r) return ;
}
return ;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
const char LL[]="%I64d\n";
#endif
srand(time());
n=read(),m=read();
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=m;i++) b[i].s=read(),b[i].f=read(),b[i].c=read(),b[i].r=read();
random_shuffle(b+,b+m+);
for (int i=;i<=m;i++)
if (!check(ans,i))
{
ll l=ans+,r=1000000000000000000ll;
while (l<=r)
{
ll mid=l+r>>;
if (check(mid,i)) ans=mid,r=mid-;
else l=mid+;
}
}
cout<<ans;
return ;
//NOTICE LONG LONG!!!!!
}