A题:sb题。。。。就判断一下哪边最大即可。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 305
#define maxm 20005
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head
pii p[maxn];
int n;
void work()
{
int x, a;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &x, &a);
p[i] = mp(x, a);
}
sort(p+1, p+n+1);
int t = lower_bound(p+1, p+n+1, mp(0, 0)) - p - 1;
int t2 = n - t;
t2 = min(t, t2);
int ans1 = 0, ans2 = 0;
for(int i = t; i >= max(1, t - t2); i--) {
ans1 += p[i].second;
}
for(int i = t+1; i <= min(n, t + t2); i++) {
ans1 += p[i].second;
}
for(int i = t; i >= max(1, t - t2 + 1); i--) {
ans2 += p[i].second;
}
for(int i = t+1; i <= min(n, t + t2 + 1); i++) {
ans2 += p[i].second;
}
printf("%d\n", max(ans1, ans2));
}
int main()
{
work();
return 0;
}
B题:sb题。。判断一下每个数的最左最右。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 1000005
#define maxm 2000005
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head
int a[maxn];
int c1[maxn];
int c2[maxn];
int cnt[maxn];
int n;
void work()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
memset(c1, 0, sizeof c1);
memset(c2, 0, sizeof c2);
for(int i = 1; i <= n; i++) c2[a[i]] = i;
for(int i = n; i >= 1; i--) c1[a[i]] = i;
for(int i = 1; i <= n; i++) cnt[a[i]]++;
int mx = 0;
for(int i = 1; i <= 1e6; i++) mx = max(mx, cnt[i]);
int ans1 = -1, ans2 = -1, ans = INF;
for(int i = 1; i <= n; i++) {
if(cnt[a[i]] != mx) continue;
int t = c2[a[i]] - c1[a[i]] + 1;
if(t < ans) {
ans = t;
ans1 = c1[a[i]];
ans2 = c2[a[i]];
}
}
printf("%d %d\n", ans1, ans2);
}
int main()
{
work();
return 0;
}
C题:有点思维难度。。。先搞出可以到达的最终数字的最小值。。。然后处理出每个数到这个最小值只剩2的倍数的最小值。。。再处理这个数还要除掉几次到达最小值。。取中位数就行了。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 100005
#define maxm 200005
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head
multiset<int> s;
multiset<int>::iterator it;
map<int, int> mpp;
int a[maxn];
int n;
void work()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) {
mpp[a[i]]++;
s.insert(a[i]);
}
int t;
while(1) {
t = *(--s.end());
if(mpp[t] == n) break;
mpp[t]--;
it = s.find(t);
s.erase(it);
mpp[t / 2]++;
s.insert(t / 2);
}
int ans = 0;
for(int i = 1; i <= n; i++) {
int tt = t;
while(tt <= a[i]) tt <<= 1;
tt /= 2;
tt ^= a[i];
int res = 0;
while(tt) res++, tt >>= 1;
ans += res;
for(int j = 0; j < res; j++) a[i] /= 2;
res = 0;
while(a[i] != t) a[i] /= 2, res++;
a[i] = res;
}
sort(a+1, a+n+1);
int tt = a[(n + 1) / 2];
for(int i = 1; i <= n; i++) ans += abs(a[i] - tt);
printf("%d\n", ans);
}
int main()
{
work();
return 0;
}
D题:把真拆成左右两个假。。。然后排序,判断一下就行了。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 400005
#define maxm 400005
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head
pair<LL, LL> a[maxn];
LL two[maxn];
LL sum[maxn];
int n, h, cnt;
void work()
{
int id, op;
LL L, R;
scanf("%d%d", &h, &n);
cnt = 0;
two[1] = 1;
for(int i = 2; i <= h; i++) two[i] = two[i-1] * 2;
for(int i = 1; i <= h; i++) sum[i] = sum[i-1] + two[i];
for(int i = 1; i <= n; i++) {
scanf("%d%I64d%I64d%d", &id, &L, &R, &op);
L -= sum[id-1];
R -= sum[id-1];
while(id < h) {
id++;
L = 2 * L - 1;
R = 2 * R;
}
if(op == 0) a[cnt++] = mp(L, R);
else {
if(L > 1) a[cnt++] = mp(1, L-1);
if(R < two[h]) a[cnt++] = mp(R+1, two[h]);
}
}
LL ans = -1, now = 1, t = 0;
sort(a, a+cnt);
for(int i = 0; i < cnt; i++) {
if(a[i].first > now) {
ans = now;
t += a[i].first - now;
}
now = max(now, a[i].second + 1);
}
if(two[h] >= now) {
ans = now;
t += two[h] - now + 1;
}
if(t == 0) printf("Game cheated!\n");
else if(t > 1) printf("Data not sufficient!\n");
else printf("%I64d\n", ans + sum[h-1]);
}
int main()
{
work();
return 0;
}
E题:线段树。。先按字母建立26棵线段树。。。每次操作就是对该区间的26棵线段树先26次区间更新,再26次按升序或降序区间更新。。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 100005
#define maxm 200005
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head
char s[maxn];
int Sum[26][maxn << 2];
int Lazy[26][maxn << 2];
int a[maxn];
int c[30];
int n, m;
void pushup(int sum[], int o)
{
sum[o] = sum[ls] + sum[rs];
}
void pushdown(int sum[], int lazy[], int o, int L, int R)
{
if(lazy[o] != -1) {
int mid = (L + R) >> 1;
sum[ls] = (mid - L + 1) * lazy[o];
sum[rs] = (R - mid) * lazy[o];
lazy[ls] = lazy[rs] = lazy[o];
lazy[o] = -1;
}
}
void build(int sum[], int lazy[], int o, int L, int R, int rt)
{
lazy[o] = -1;
if(L == R) {
if(rt == a[L]) sum[o] = 1;
else sum[o] = 0;
return;
}
int mid = (L + R) >> 1;
build(sum, lazy, lson, rt);
build(sum, lazy, rson, rt);
pushup(sum, o);
}
void update(int sum[], int lazy[], int o, int L, int R, int ql, int qr, int k)
{
if(ql <= L && qr >= R) {
sum[o] = k * (R - L + 1);
lazy[o] = k;
return;
}
pushdown(sum, lazy, o, L, R);
int mid = (L + R) >> 1;
if(ql <= mid) update(sum, lazy, lson, ql, qr, k);
if(qr > mid) update(sum, lazy, rson, ql, qr, k);
pushup(sum, o);
}
int query(int sum[], int lazy[], int o, int L, int R, int ql, int qr)
{
if(ql <= L && qr >= R) return sum[o];
pushdown(sum, lazy, o, L, R);
int mid = (L + R) >> 1, ans = 0;
if(ql <= mid) ans += query(sum, lazy, lson, ql, qr);
if(qr > mid) ans += query(sum, lazy, rson, ql, qr);
pushup(sum, o);
return ans;
}
void solve(int l, int r, int op)
{
memset(c, 0, sizeof c);
for(int i = 0; i < 26; i++) {
c[i] += query(Sum[i], Lazy[i], 1, 1, n, l, r);
update(Sum[i], Lazy[i], 1, 1, n, l, r, 0);
}
int t = l;
if(op == 0) {
for(int i = 25; i >= 0; i--) {
if(c[i] == 0) continue;
update(Sum[i], Lazy[i], 1, 1, n, t, t + c[i] - 1, 1);
t += c[i];
}
}
else {
for(int i = 0; i < 26; i++) {
if(c[i] == 0) continue;
update(Sum[i], Lazy[i], 1, 1, n, t, t + c[i] - 1, 1);
t += c[i];
}
}
}
void work()
{
scanf("%s", s + 1);
for(int i = 1; i <= n; i++) a[i] = s[i] - 'a';
for(int i = 0; i < 26; i++) build(Sum[i], Lazy[i], 1, 1, n, i);
for(int i = 1; i <= m; i++) {
int l, r, kk;
scanf("%d%d%d", &l, &r, &kk);
solve(l, r, kk);
}
for(int i = 1; i <= n; i++) {
for(int j = 0; j < 26; j++) {
int t = query(Sum[j], Lazy[j], 1, 1, n, i, i);
if(t) {
s[i] = j + 'a';
break;
}
}
}
s[n+1] = '\0';
puts(s + 1);
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF) {
work();
}
return 0;
}