【AtCoder】AGC015

AGC015

A - A+...+B Problem

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 300005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
	if(c == '-') f = -1;
	c = getchar();
    }
    while(c >= '0' && c <= '9') {
	res = res * 10 +c - '0';
	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
	out(x / 10);
    }
    putchar('0' + x % 10);
}
int64 N,A,B;
void Solve() {
    read(N);read(A);read(B);
    if(A > B) {puts("0");return;}
    if(A == B) {puts("1");return;}
    if(N == 1) {puts("0");return;}
    out(A + B * (N - 1) - B - A * (N - 1) + 1);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

B - Evilator

如果是U的话下面的层需要坐两次,D的话上面的层需要坐两次

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
	if(c == '-') f = -1;
	c = getchar();
    }
    while(c >= '0' && c <= '9') {
	res = res * 10 +c - '0';
	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
	out(x / 10);
    }
    putchar('0' + x % 10);
}
char s[MAXN];
int64 ans;
int N;
void Solve() {
    scanf("%s",s + 1);
    N = strlen(s + 1);
    for(int i = 1 ; i <= N ; ++i) {
	if(s[i] == 'U') ans += N - i + (i - 1) * 2;
	else ans += i - 1 + (N - i) * 2;
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

C - Nuske vs Phantom Thnook

因为形成一个森林,我们只需要查询这个边框里面有多少个树根以及断开了多少父亲与儿子之间的边

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
	if(c == '-') f = -1;
	c = getchar();
    }
    while(c >= '0' && c <= '9') {
	res = res * 10 +c - '0';
	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
	out(x / 10);
    }
    putchar('0' + x % 10);
}
int N,M,Q;
char s[2005][2005];
int ch[4][2005][2005],sum[2005][2005],fa[2005 * 2005];
int dx[4] = {0,1,0,-1},dy[4] = {1,0,-1,0};
int id(int x,int y) {
    return (x - 1) * M + y;
}
int getfa(int u) {
    return fa[u] == u ? u : fa[u] = getfa(fa[u]);
}
void dfs(int x,int y) {
    for(int k = 0 ; k < 4 ; ++k) {
	int tx = x + dx[k],ty = y + dy[k];
	if(s[tx][ty] == '1') {
	    if(fa[id(x,y)] != id(tx,ty)) {
		ch[k][tx][ty] = 1;
		fa[id(tx,ty)] = id(x,y);
		dfs(tx,ty);
	    }
	}
    }
}
void Solve() {
    read(N);read(M);read(Q);
    for(int i = 1 ; i <= N ; ++i) {
	scanf("%s",s[i] + 1);
    }
    for(int i = 1 ; i <= N ; ++i) {
	for(int j = 1 ; j <= M ; ++j) {
	    if(s[i][j] == '1' && !fa[id(i,j)]) {
		sum[i][j] = 1;
		dfs(i,j);
	    }
	}
    }
    for(int i = 1 ; i <= N ; ++i) {
	for(int j = 1 ; j <= M ; ++j) {
	    sum[i][j] += sum[i][j - 1];
	}
    }
    for(int i = 1 ; i <= N ; ++i) {
	for(int j = 1 ; j <= M ; ++j) {
	    sum[i][j] += sum[i - 1][j];
	}
    }
    for(int j = 1 ; j <= M ; ++j) {
	for(int i = 1 ; i <= N ; ++i) {
	    ch[0][i][j] += ch[0][i - 1][j];
	    ch[2][i][j] += ch[2][i - 1][j];
	}
    }
    for(int i = 1 ; i <= N ; ++i) {
	for(int j = 1 ; j <= M ; ++j) {
	    ch[1][i][j] += ch[1][i][j - 1];
	    ch[3][i][j] += ch[3][i][j - 1];
	}
    }
    int x[2],y[2];
    for(int i = 1 ; i <= Q ; ++i) {
	read(x[0]);read(y[0]);read(x[1]);read(y[1]);
	int ans = 0;
	ans += ch[0][x[1]][y[0]] - ch[0][x[0] - 1][y[0]];
	ans += ch[1][x[0]][y[1]] - ch[1][x[0]][y[0] - 1];
	ans += ch[2][x[1]][y[1]] - ch[2][x[0] - 1][y[1]];
	ans += ch[3][x[1]][y[1]] - ch[3][x[1]][y[0] - 1];
	ans += sum[x[1]][y[1]] - sum[x[0] - 1][y[1]] - sum[x[1]][y[0] - 1] + sum[x[0] - 1][y[0] - 1]; 
	out(ans);enter;
    }
    
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

D - A or...or B Problem

找到\(A\)\(B\)第一个不同的最高位是\(T = 2^{r}\)

然后只保留\(A\)\(B\)的后\(r\)

分成两个集合

\(\{A,A + 1....T - 1\}\)\(\{T,T + 1...B\}\)

第一个集合能得到的数的区间是\([A,T - 1]\)

第二个集合除了第\(r\)位能得到的最高位是\(k\),能得到的区间为\([T,2^{r} + 2^{k + 1} - 1]\)

两个集合加一起能得到的区间是\([T + A,2T - 1]\)

区间求并即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
	if(c == '-') f = -1;
	c = getchar();
    }
    while(c >= '0' && c <= '9') {
	res = res * 10 +c - '0';
	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
	out(x / 10);
    }
    putchar('0' + x % 10);
}
pair<int64,int64> p[5];
void Solve() {
    int64 A,B;
    read(A);read(B);
    if(A == B) {puts("1");return;}
    int r = -1;
    for(int i = 59 ; i >= 0 ; --i) {
	if((A >> i & 1) != (B >> i & 1)) {r = i;break;}
    }
    int64 ans = 0;
    A &= (1LL << r + 1) - 1;
    B &= (1LL << r + 1) - 1;
    p[1] = mp((1LL << r) + A,(1LL << r + 1) - 1);
    int t = -1;
    for(int i = r - 1 ; i >= 0 ; --i) {
	if(B >> i & 1) {t = i;break;}
    }
    p[0] = mp(A,(1LL << r) + (1LL << t + 1) - 1);
    sort(p,p + 2);
    int64 rm = -1;
    for(int i = 0 ; i < 2 ; ++i) {
	if(p[i].se < rm) continue;
	else {
	    ans += p[i].se - max(rm,p[i].fi - 1);
	    rm = p[i].se;
	}
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

E - Mr.Aoki Incubator

按照速度排序的话,如果选择一个点,能影响到的点是坐标值大于它且速度最小的到坐标值小于它且速度最大的点这个区间

这些区间排序后左右端点不降

然后可以用一个dp+前缀和统计一下覆盖全局的方案数

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
	if(c == '-') f = -1;
	c = getchar();
    }
    while(c >= '0' && c <= '9') {
	res = res * 10 +c - '0';
	c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
	out(x / 10);
    }
    putchar('0' + x % 10);
}
const int MOD = 1000000007;
int N;
pii p[MAXN],rg[MAXN];
int L[MAXN],R[MAXN],st[MAXN],top;
int dp[MAXN],s[MAXN];
vector<int> v[MAXN];
int inc(int a,int b) {
    return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
    return 1LL * a * b % MOD;
}
void update(int &x,int y) {
    x = inc(x,y);
}
void Solve() {
    read(N);
    int x,v;
    for(int i = 1 ; i <= N ; ++i) {
	read(x);read(v);p[i] = mp(v,x);
    }
    sort(p + 1,p + N + 1);
    
    for(int i = 1 ; i <= N ; ++i) {
	rg[i].fi = i;
	if(!top || p[st[top]].se < p[i].se) st[++top] = i;
	if(top) {
	    int l = 1,r = top;
	    while(l < r) {
		int mid = (l + r) >> 1;
		if(p[st[mid]].se >= p[i].se) r = mid;
		else l = mid + 1;
	    }
	    rg[i].fi = st[l];
	}
	
    }
    top = 0;
    for(int i = N ; i >= 1 ; --i) {
	rg[i].se = i;
	if(!top || p[st[top]].se > p[i].se) st[++top] = i;
	if(top) {
	    int l = 1,r = top;
	    while(l < r) {
		int mid = (l + r) >> 1;
		if(p[st[mid]].se <= p[i].se) r = mid;
		else l = mid + 1;
	    }
	    rg[i].se = st[l];
	}
	
    }
    sort(rg + 1,rg + N + 1);
    s[0] = 1;dp[0] = 1;
    int k = 1;
    for(int i = 1 ; i <= N ; ++i) {
	while(k <= rg[i].se) {
	    s[k] = inc(s[k - 1],dp[k]);
	    ++k;
	}
	int t = s[rg[i].se];
	if(rg[i].fi != 1) update(t,MOD - s[rg[i].fi - 2]);
	update(dp[rg[i].se],t);
	
	s[rg[i].se] = inc(s[rg[i].se - 1],dp[rg[i].se]);
    }
    out(dp[N]);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
}

F结论题,看不懂,咕了

posted @ 2019-04-09 20:25  sigongzi  阅读(193)  评论(0编辑  收藏  举报