2019 ICPC Universidad Nacional de Colombia Programming Contest 题解
A:貌似是计算几何
#include<bits/stdc++.h>
using namespace std;
struct vec{
int x,y;
vec(int _x,int _y):x(_x),y(_y){
int d=__gcd(x,y);
x/=d,y/=d;
if(x<0)x=-x,y=-y;
if(x==0)y=abs(y);
}
bool operator==(vec b)const{
return x==b.x&&y==b.y;
}
bool operator<(vec b)const{
if(x!=b.x){
return x<b.x;
}
return y<b.y;
}
};
int main()
{
int T;
cin>>T;
while(T--){
int n;
cin>>n;
map<vec,int>cnt;
long long ans=0;
vector<pair<vec,int>>v;
while(n--){
int x1,x2,y1,y2;
cin>>x1>>y1>>x2>>y2;
vec t(x1-x2,y1-y2);
v.push_back({t,t.x*y1-t.y*x1});
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for(auto i:v){
vec t=i.first;
ans+=cnt[vec(-t.y,t.x)];
cnt[t]++;
}
cout<<ans<<'\n';
}
}
B:母鸡,队友写的
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 5e3 + 10;
string s;
int main()
{
cin >> s;
for (int len = 0; len <= s.length(); len++)
{
string tmp = s.substr(0, len);
reverse(tmp.begin(), tmp.end());
string check = s + tmp;
string cur = check;
reverse(cur.begin(), cur.end());
if (check == cur)
{
cout << check << endl;
return 0;
}
}
}
C:dp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
char s1[N],s2[N];
int dp[1005][1005];
int main(){
scanf(" %s %s",s1+1,s2+1);
int n=strlen(s1+1);
int m=min(n,1000);
int ans=0;
for(int i=0;i<=m;i++)
for(int j=0;j<=m;j++){
int t1=0;
if(i)t1=dp[i-1][j];
while(t1+i+1<=n&&t1+j+1<=n&&s1[t1+i+1]==s2[t1+j+1])t1++;
int t2=0;
if(j)t2=dp[i][j-1];
while(t2+i+1<=n&&t2+j+1<=n&&s1[t2+i+1]==s2[t2+j+1])t2++;
dp[i][j]=max(t1,t2);
ans=max(ans,dp[i][j]);
}
if(ans*100>=99*n)puts("Long lost brothers D:");
else puts("Not brothers :(");
}
D:数据结构
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
char s[N];
int fa[N][150];
struct node{
int i,a,k;char c;
}q[N];
int _find(int x,int y){
if(fa[x][y]==x)return x;
else return fa[x][y]=_find(fa[x][y],y);
}
bool vis[N];
int main(){
scanf(" %s",s+1);
int n=strlen(s+1);
int x=150;
for(int i=1;i<=x;i++)
for(int j=1;j<=n+1;j++)fa[j][i]=j;
int m;scanf("%d",&m);
for(int i=1;i<=m;i++)scanf("%d %d %d %c",&q[i].i,&q[i].a,&q[i].k,&q[i].c);
for(int i=m;i>=1;i--){
if(q[i].a>x){
int k=q[i].k,c=q[i].c,p=q[i].i,a=q[i].a;
for(int i=0;i<=k;i++){
int be=p+i*a;
if(!vis[be]){
vis[be]=true;
s[be]=c;
for(int j=1;j<=x;j++)
fa[be][j]=min(_find(be,j)+j,n+1);
}
}
}else{
int k=q[i].k,c=q[i].c,p=q[i].i,a=q[i].a;
for(int be=_find(p,a);be<=p+k*a;be=_find(be,a)){
if(!vis[be]){
vis[be]=true;
s[be]=c;
for(int j=1;j<=x;j++)
fa[be][j]=min(_find(be,j)+j,n+1);
}
}
}
}
printf("%s\n",s+1);
}
E:扫描线
#include <bits/stdc++.h>
#define eps 1e-8
using namespace std;
const int N=1e5+10;
int maxx[N<<2],lazy[N<<2],n,d,len;
struct node{
int pos,h;
bool operator<(const node &a)const{
return pos<a.pos;
}
}q[N<<1];
void push_up(int rt){
maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
}
void push_down(int rt){
if(lazy[rt]){
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
maxx[rt<<1]+=lazy[rt];
maxx[rt<<1|1]+=lazy[rt];
lazy[rt]=0;
}
}
void update(int l,int r,int L,int R,int val,int rt){
if(L<=l&&r<=R){
maxx[rt]+=val;lazy[rt]+=val;return ;
}
push_down(rt);int mid=(l+r)>>1;
if(L<=mid)update(l,mid,L,R,val,rt<<1);
if(mid<R)update(mid+1,r,L,R,val,rt<<1|1);
push_up(rt);
}
int main()
{
double x;scanf("%d %d %lf",&n,&d,&x);
len=100*(x+eps);
for(int i=1;i<=n;i++){
scanf("%d %lf",&q[i].h,&x);q[i].pos=(x+eps)*100;
}
sort(q+1,q+n+1);
for(int i=1;i<=n;i++)q[i+n]=q[i],q[i+n].pos+=36000;
n<<=1;
int nowp=1,ans=0;
for(int i=1;i<=n;i++){
int k=i;
while(k<=n&&q[k].pos==q[i].pos){
update(1,100000,max(q[k].h-d,1),q[k].h,1,1);k++;
}
i=k-1;
while(q[nowp].pos+len<q[i].pos){
update(1,100000,max(q[nowp].h-d,1),q[nowp].h,-1,1);nowp++;
}
ans=max(ans,maxx[1]);
}
printf("%d\n",ans);
return 0;
}
F:强模
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 2e5 + 10;
string s;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
typedef pair<ll,ll> PII;
PII sub(PII p1, PII p2)
{
ll a = p1.first, b = p1.second;
ll c = p2.first, d = p2.second;
ll fz = a * d - b * c;
ll fm = b * d;
ll g = gcd(abs(fz), abs(fm));
fz /= g, fm /= g;
return {fz, fm};
}
PII add(PII p1, PII p2)
{
ll a = p1.first, b = p1.second;
ll c = p2.first, d = p2.second;
ll fz = a * d + b * c;
ll fm = b * d;
ll g =gcd(abs(fz), abs(fm));
fz /= g, fm /= g;
return {fz, fm};
}
int main()
{
while (cin >> s)
{
stack<int>st;
PII ans=make_pair(0,1);
int op1=1,op2=1;
for (int i = 0; i < s.length(); i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
ll val1 = 0, val2 = 0;
int j = i;
while (s[j] != '/')
{
val1 = val1 * 10 + s[j] - '0';
j++;
}
j++;
while (s[j] >= '0' && s[j] <= '9')
{
val2 = val2 * 10 + s[j] - '0';
j++;
}
PII t={val1,val2};
if(op1*op2==1)ans=add(ans,t);
else ans=sub(ans,t);
i = j - 1;
}
else if (s[i] == '(') {
op1=1;
if(s[i-1]=='-'){
op2*=-1;st.push(-1);
}else st.push(1);
}
else if (s[i] == '+' || s[i] == '-')
{
op1=s[i]=='+'?1:-1;
}
else if (s[i] == ')')
{
op2*=st.top();st.pop();
}
}
cout << ans.first << "/" << ans.second<< "\n";
}
return 0;
}
G:母鸡
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e4 + 10;
int n, k, a[N];
int deg[N], depth[N], fa[N];
vector<int>v[N];
void dfs(int val, int deep)
{
depth[val] = deep;
for (auto x: v[val]) dfs(x, deep + 1);
return;
}
typedef pair<int,int> PII;
priority_queue<PII, vector<PII>, greater<PII> >qu;
int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
{
v[a[i]].push_back(i);
fa[i] = a[i];
deg[a[i]]++;
}
dfs(0, 0);
for (int i = 1; i <= n; i++)
if (!deg[i]) qu.push({-depth[i], i});
int cnt = 0;
while (!qu.empty())
{
cnt++;
vector<int>cur;
cur.clear();
for (int i = 1; i <= k && !qu.empty(); i++)
{
int val = qu.top().second;
qu.pop();
cur.push_back(val);
}
for (auto x: cur)
{
deg[fa[x]]--;
if (!deg[fa[x]] && fa[x] != 0)
qu.push({-depth[fa[x]], fa[x]});
}
}
printf("%d\n", cnt);
return 0;
}
H:搜索
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e15+37;
const int N=5e6;
string s[3];
int cnt1,cnt2,now;
ll pow12[35];
ll a[N],b[N];
void dfs(int pos,int m,ll sum,int op,int n,ll a[]){
if(pos==m){a[now++]=sum;return ;}
for(int i=0;i<3;i++){
ll sum1=(sum+s[i][pos]*pow12[n-pos-1]%mod)%mod;
dfs(pos+1,m,sum1,op,n,a);
}
}
ll solve(int n){
a[0]=b[0]=0;
now=0;
dfs(0,n/2,0,0,n,a);
cnt1=now;
now=0;
dfs(n/2,n,0,1,n,b);
cnt2=now;
sort(a,a+cnt1);
sort(b,b+cnt2);
ll ans=(a[0]+b[0])%mod;
a[cnt1]=a[0]+mod,b[cnt2]=b[0]+mod;
int pos=cnt2;
for(int i=0;i<cnt1;i++){
while(pos>0&&b[pos-1]+a[i]>=mod)pos--;
ans=min(ans,(b[pos]+a[i])%mod)%mod;
}
return ans;
}
int main()
{
pow12[0]=1;
for(int i=1;i<30;i++)pow12[i]=pow12[i-1]*127%mod;
int n,m;
scanf("%d %d",&n,&m);
for(int i=0;i<3;i++)cin>>s[i];
ll ans1=solve(n);
for(int i=0;i<3;i++)cin>>s[i];
ll ans2=solve(m);
if(ans1<ans2)puts("Owls");
else if(ans1>ans2)puts("Goats");
else puts("Tie");
return 0;
}
I:不知道
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 2e5 + 10;
string s;
int main()
{
cin >> s;
int pos = -1;
for (int i = 0; s[i]; i++)
{
if (s[i] >= '0' && s[i] <= '9') pos = i;
else break;
}
if (pos == -1) cout << -1 << endl;
else cout << s.substr(0, pos + 1);
return 0;
}
J:线段树
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
int n,m,a[N];
int len[N<<2];
ll sum[N<<2],lazy[N<<2],minx[N<<2];
void push_up(int rt){
len[rt]=len[rt<<1]+len[rt<<1|1];
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
minx[rt]=min(minx[rt<<1],minx[rt<<1|1]);
}
void push_down(int rt,int l,int r){
if(lazy[rt]){
int mid=(l+r)>>1;
sum[rt<<1]-=len[rt<<1]*lazy[rt];
minx[rt<<1]-=lazy[rt];
lazy[rt<<1]+=lazy[rt];
sum[rt<<1|1]-=len[rt<<1|1]*lazy[rt];
minx[rt<<1|1]-=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
lazy[rt]=0;
}
}
void build(int l,int r,int rt){
if(l==r){sum[rt]=a[l];minx[rt]=a[l];len[rt]=1;return ;}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
push_up(rt);
}
void update(int l,int r,int L,int R,int x,int rt){
if(l==r){
if(sum[rt]>x){
sum[rt]-=x;
minx[rt]-=x;
}else {
sum[rt]=0;
minx[rt]=INF;
len[rt]=0;
}
return ;
}
if(L<=l&&r<=R&&minx[rt]>=x){
minx[rt]-=x;
sum[rt]-=len[rt]*1ll*x;
lazy[rt]+=x;return ;
}
push_down(rt,l,r);
int mid=(l+r)>>1;
if(L<=mid&&len[rt<<1]>0)update(l,mid,L,R,x,rt<<1);
if(mid<R&&len[rt<<1|1]>0)update(mid+1,r,L,R,x,rt<<1|1);
push_up(rt);
}
ll query(int l,int r,int L,int R,int rt){
if(L<=l&&r<=R)return sum[rt];
push_down(rt,l,r);
ll sum=0;int mid=(l+r)>>1;
if(L<=mid)sum+=query(l,mid,L,R,rt<<1);
if(mid<R)sum+=query(mid+1,r,L,R,rt<<1|1);
return sum;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build(1,n,1);
while(m--){
int op;scanf("%d",&op);
if(op==1){
int x,y;scanf("%d %d",&x,&y);
if(x>y){
ll sum1=query(1,n,x,n,1);
ll sum2=query(1,n,1,y,1);
printf("%lld\n",sum1+sum2);
}else printf("%lld\n",query(1,n,x,y,1));
}else {
int x,y,z;scanf("%d %d %d",&x,&y,&z);
if(x>y){
update(1,n,x,n,z,1);
update(1,n,1,y,z,1);
}
else update(1,n,x,y,z,1);
}
}
}
K:母鸡
#include<bits/stdc++.h>
using namespace std;
const int N=2e5;
char f[N+10];
int pre[N];
int main()
{
f[1]=f[2]=1;
for(int i=3;i<=N;i++){
f[i]=f[i-1]+f[i-2];
f[i]&=1;
}
pre[1]=0;
for(int i=2;i<=N;i++){
pre[i]=pre[i-1]+(f[i]^f[i-1]);
}
int T;
cin>>T;
while(T--){
int n;
cin>>n;
if(n<=2){
cout<<0<<'\n';
continue;
}
cout<<pre[n]+1<<'\n';
}
}
L:母鸡
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
bool dp[maxn];
int pre[maxn], p[maxn];
int n, a[105], vis[105];
int cnt[maxn];
void check(int mid)
{
int now = cnt[mid];
memset(vis, 0, sizeof(vis));
while (now) {
vis[p[now - pre[now]]]++;
now = pre[now];
}
printf("1\n");
for (int i = 1; i <= n; i++)
printf("%d ", vis[i]);
printf("\n");
fflush(stdout);
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
int limit = 1e6;
dp[0] = true;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= limit - a[i]; j++)
if (dp[j])
dp[j + a[i]] = true,
pre[j + a[i]] = j;
}
int k = 0;
for (int i = 1; i <= limit; i++)
if (dp[i])
cnt[++k] = i;
for (int i = 1; i <= n; i++)
p[a[i]] = i;
char s[20];
int left = 0, right = k, mid, ans = -1;
int tl=0,tr=1e6;
while (left <= right) {
mid = (left + right) >> 1;
check(mid);
scanf("%s", s + 1);
if (s[1] == 'y') {
ans = cnt[mid];
break;
} else if (s[1] == 'g')
left = mid + 1,tl=cnt[mid]+1;
else
right = mid - 1,tr=cnt[mid]-1;
}
if(tr==tl)ans=tl;
printf("2\n%d\n", ans);
fflush(stdout);
return 0;
}