清北考前刷题day6下午好

/*
贪心 负数一定不取
枚举最高位是1 且答案取为0的 位置, 更新答案。
*/
#include<iostream>
#include<cstdio>
#include<cstring>

#define ll long long
#define N 100010

using namespace std;
int n;
ll a[N],ans,sum[N];
char s[N];

ll read()
{
    ll x=0,f=1;char c=getchar();
    while(c>‘9‘||c<‘0‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}

int main()
{
    freopen("maximum.in","r",stdin);
    freopen("maximum.out","w",stdout);
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        a[i]=read();
        sum[i]=sum[i-1];
        if(a[i]>0)sum[i]=sum[i-1]+a[i];
    }
    scanf("%s",s+1);
    ll c=0;
    for(int i=n; i>=1; i--)
      if(s[i]==‘1‘)
      {
          ans=max(ans,c+sum[i-1]);
          c+=max(a[i],0LL);
      }
    ans=max(ans,c);
    printf("%I64d\n",ans);
    return 0;
}

/*
15暴力
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

#define N 1010

using namespace std;
int n,k;
int l,r,mid;
int num[N],tmp[N];
int ans;

int minn(int a,int b,int i)
{
    if(a<b) return tmp[i-1];
    else return tmp[i-1]+mid;
}

bool check()
{
    int sum=0;
    for(int i=1; i<=n; i++)    tmp[i]=num[i];
    for(int i=2; i<=n; i++)
        if(abs(tmp[i]-tmp[i-1])>mid)
        {
            if(tmp[i+1]>tmp[i]) tmp[i]=max(tmp[i],tmp[i-1]+mid);
            else tmp[i]=minn(abs(tmp[i-1]-tmp[i+1]),tmp[i-1]+mid-tmp[i+1],i);
            sum++;
        }
    if(sum>k)    return false;
    else return true;
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1; i<=n; i++)    scanf("%d",&num[i]);
    l=0;
    r=1000000000;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(check())    ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d",ans);
}

不会分块

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
const int maxn = 200000;
const int len = 400;
int n, A, B,m;
int a[maxn],b[maxn],l[maxn],r[maxn],lb[maxn],tot;
int answer[300][300];
int rt[300][maxn], lt[300][maxn],d[maxn];
//int root[maxn*len], ll[maxn*len], rr[maxn*len],data[maxn*len];
int find(int x)
{
    for (int l = 0, r = m; l < r;)
    {
        int mid = (l + r) / 2;
        if (b[mid] == x) return mid;
        if (b[mid]>x) r = mid;
        else l = mid + 1;
    }
    return -1;
}
/*int build(int l, int r)
{
 if (l == r)
 {
  tot++;
  ll[tot] = rr[tot] = 0;
  data[tot] = d[l];
  return tot;
 }
 tot++;
 int tmp = tot;
 ll[tmp] = build(l, (l + r) / 2);
 rr[tmp] = build((l + r) / 2 + 1, r);
 data[tmp] = min(data[ll[tmp]], data[rr[tmp]]);
 return tmp;
}
int change(int i, int l, int r,int x)
{
 if (l == x && r == x)
 {
  tot++;
  ll[tot] = rr[tot] = 0;
  data[tot] = n + 1;
  return tot;
 }
 tot++;
 int tmp = tot;
 ll[tot] = ll[i];
 rr[tot] = rr[i];
 if (l <= x && x <= (l + r) / 2) ll[tmp] = change(ll[i], l, (l + r) / 2, x);
 else rr[tmp] = change(rr[i], (l + r) / 2 + 1, r, x);
 data[tmp] = min(data[ll[tmp]], data[rr[tmp]]);
 return tmp;
}
int check(int i, int l, int r, int x, int &ans)
{
 if (l > x) return 0;
 if (1 <= l && r <= x)
 {
  ans = min(ans, data[i]); return 0;
 }
 check(ll[i], l, (l + r) / 2, x, ans);
 check(rr[i], (l + r) / 2 + 1, r, x, ans);
 return 0;
}*/
int main()
{
    double ti = clock();
    freopen("sequence.in", "r", stdin);
    freopen("sequence.out", "w", stdout);
    scanf("%d%d%d", &n, &A, &B);
    a[0] = 0;
    for (int i = 1; i <= n; i++)
    {
        char c;
        for (scanf(" %c", &c); c != ‘A‘ && c != ‘B‘; scanf(" %c", &c));
        if (c == ‘A‘) a[i] = a[i - 1] + B;
        else a[i] = a[i - 1] - A;
    }
    for (int i = 0; i <= n; i++) b[i] = a[i];
    sort(b, b + n + 1);
    m = unique(b, b + n + 1) - b;
    for (int i = 0; i <= n; i++)
    {
        a[i] = find(a[i]);
        if (a[i] == -1)
        {
            printf("???\n");
            return 0;
        }
    }
    n++;
    int k = n / len;
    for (int i = 0; i <= k; i++)
    {
        int ans = 0;
        tot++;
        for (int j = i*len; j < n; j++)
        {
            if (j%len == 0)
            {
                answer[i][j / len] = ans;
            }
            if (lb[a[j]] != tot)
            {
                lb[a[j]] = tot;
                l[a[j]] = j;
            }
            ans = max(ans, j - l[a[j]]);
        }
    }
    for (int i = 0; i < n; i++) r[i] = -1;
    for (int i = 0; i < n; i++)
    {
        r[a[i]] = i;
        if (i%len == len - 1)
        {
            int tmp = i / len;
            for (int j = 0; j < n; j++)
                rt[tmp][j] = r[j];
        }
    }
    for (int i = 0; i < n; i++) l[i] = -1;
    for (int i = n - 1; i >= 0; i--)
    {
        l[a[i]] = i;
        if (i%len == 0)
        {
            int tmp = i / len;
            for (int j = 0; j < n; j++)
                lt[tmp][j] = l[j];
        }
    }
    int q;
    scanf("%d", &q);
    int ans = 0;
    for (; q; q--)
    {
        int L, R;
        scanf("%d%d", &L, &R);
        L--;
        int kl = L / len, kr = R / len;
        ans = 0;
        if (kl == kr)
        {
            tot++;
            for (int i = L; i <= R; i++)
            {
                if (lb[a[i]] != tot)
                {
                    lb[a[i]] = tot;
                    l[a[i]] = i;
                }
                ans = max(ans, i - l[a[i]]);
            }
        }
        else
        {
            ans = answer[kl + 1][kr];
            tot++;
            int tmp = min(n, (kl + 1)*len);
            for (int i = L; i < tmp; i++)
            {
                if (lb[a[i]] != tot)
                {
                    lb[a[i]] = tot;
                    l[a[i]] = i;
                    ans = max(ans, rt[kr - 1][a[i]] - i);
                }
            }
            tmp = min(R + 1, n);
            for (int i = kr*len; i < tmp; i++)
            {
                if (lb[a[i]] != tot)
                {
                    if (lt[kl + 1][a[i]] != -1) ans = max(ans, i - lt[kl + 1][a[i]]);
                }
                else ans = max(ans, i - l[a[i]]);
            }
        }
        printf("%d\n", ans);
    }
    /*int q;
    for (scanf("%d", &q); q; q--)
    {
     // if (q % 5000 == 0) cerr << q << endl;
     int L, R;
     tot++;
     scanf("%d%d", &L, &R);
     int ans = 0;
     for (int i = L - 1; i <= R; i++)
     {
      if (lb[a[i]] != tot)
      {
       lb[a[i]] = tot;
       l[a[i]] = i;
      }
      ans = max(ans, i - l[a[i]]);
     }
     printf("%d\n", ans);
    }*/
    /*for (int i = 0; i <= n; i++)
    {
     if (lb[a[i]] == 0)
     {
      lb[a[i]] = 1;
      l[a[i]] = i;
      d[i] = n + 1;
     }
     else
     {
      r[l[a[i]]] = i;
      d[i] = i - l[a[i]];
      l[a[i]] = i;
     }
    }
    root[0] = build(1, n);
    for (int i = 1; i <= n; i++)
    {
     if (r[i-1] != 0) root[i] = change(root[i - 1], 1, n, r[i-1]);
     else root[i] = root[i - 1];
    }
    int q;
    for (scanf("%d", &q); q; q--)
    {
     int L, R;
     scanf("%d%d", &L, &R);
     L--;
     int ans = n + 1;
     check(root[L], 1, n, R, ans);
     if (ans == n + 1) printf("-1\n"); else printf("%d\n", ans);
    }*/
    /* int q;
     int tans = 0;
     for (scanf("%d", &q); q; q--)
     {
      int L, R;
      scanf("%d%d", &L, &R);
      L--;
      tot++;
      int ans = n + 1;
      for (int i = L; i <= R; i++)
      {
       if (lb[a[i]] != tot)
       {
        lb[a[i]] = tot;
        l[a[i]] = i;
       }
       else
       {
        ans = min(ans, i - l[a[i]]);
        l[a[i]] = i;
       }
      }
      if (ans == n + 1) printf("-1\n"); else  {
       printf("%d\n", ans);
       tans = max(tans, ans);
      }
     }
     cerr << clock()-ti << " "<<tans<<" "<<A<<" "<<B<<endl;*/
    return 0;
}

std

时间: 2024-11-12 15:29:25

清北考前刷题day6下午好的相关文章

清北考前刷题da7下午好

三向城 /* 原图一定是一棵完全二叉树. 根节点是x,左节点是x*2,右节点是x*2+1 转化为二进制往左右走就很明显了. */ #include<iostream> #include<cstdio> #include<cstring> #define ll long long using namespace std; int T,x,y,k,ans,pos; inline int read() { int x=0,f=1;char c=getchar(); while

清北考前刷题day7早安

# 清北冬令营真题泛做

清北冬令营真题泛做 前言 这段时间为了准备冬令营把清北冬令营真题都做了一下.更个博回顾一下(免得你们老说我咕咕咕). 先写良心PKU的题再写THU的题, 主要是THU的题和PKU比起来真的毒瘤好多...... PKUWC2018 [PKUWC2018]Minimax 一个比较显然的暴力是归并排序,每次直接前后缀计算答案即可. 为啥不用线段树合并代替归并排序呢? 暴力线段树合并,合并的过程中顺便算一下即可,由于权值区间不交所以复杂度一个\(log\). [PKUWC2018]Slay the Sp

2017 清北济南考前刷题Day 3 morning

实际得分:100+0+0=100 T1 右上角是必败态,然后推下去 发现同行全是必胜态或全是必败态,不同行必胜必败交叉 列同行 所以n,m 只要有一个是偶数,先手必胜 #include<cstdio> using namespace std; int main() { freopen("star.in","r",stdin); freopen("star.out","w",stdout); int n,m; whi

2017 清北济南考前刷题Day 2 morning

期望得分:100+30+60=190 实际得分:100+30+30=160 T1 最优方案跳的高度一定是单调的 所以先按高度排序 dp[i][j] 跳了i次跳到j 枚举从哪儿跳到j转移即可 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 51 struct node { int c,h; }e[N]

2017 清北济南考前刷题Day 5 afternoon

期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using namespace std; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } #define N 1002

2017 清北济南考前刷题Day 1 morning

期望得分:100+100+50=250 实际得分:100+60+50=210 T2 二分 估错上界.估错复杂度 T1 立方数(cubic) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数,例如1,8,27就是最小的3个立方数. 现在给定一个数P,LYK想要知道这个数是不是立方数. 当然你有可能随机输出一些莫名其妙的东西来骗分,因此LYK有T次询问~ 输入格式(cub

2017 清北济南考前刷题Day 5 morning

期望得分:100+100+0=200 实际得分: 坐标的每一位不是0就是1,所以答案就是 C(n,k) #include<cstdio> #include<iostream> using namespace std; const int mod=1e9+7; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0';

清北第一套题(zhx)

死亡 [问题描述] 现在有个位置可以打sif,有个人在排队等着打sif.现在告诉你前个人每个人需要多长的时间打sif,问你第个人什么时候才能打sif.(前个人必须按照顺序来) [输入格式] 第一行两个整数如上所述. 接下来行每行一个整数代表每个人所需要用的时间. [输出格式] 一行一个整数表示答案. [样例输入] 3 2 1 1 1 [样例输出] 1 [样例解释] 山里有座庙. [数据规模与约定] 对于的100%数据,每个人所需用的时间不超过10^5. 测试点     测试点     1 10