Codeforces Round #223 (Div. 1)

题目:http://codeforces.com/contest/380

A

题意:实现两种操作

1 在数组的最后插入一个数; 2将数组的钱L部分复制c次, 问任意位置的元素值

思路:递归求解, 每次执行操作后记录下当前数组的总长度和此操作的类型,求解时二分查找该位置为第P次操作,若该操作为1, 则直接输出答案,否则计算该位置为复制前L长的位置v,递归求解

#include 
    
    
     
     
int a[100010], b[100010], ans[100010];
__int64 f[100010];
int k, n, m;
int binsearch(__int64 x)
{
  int l = 1, r = n;
  int ans = 0;
  while(l <= r)
    {
      int m = (l+r) / 2;
      if(f[m] < x)
        {
          ans = m;
          l = m+1;
        }
      else
        r = m-1;
    }
  return ans;
}
int solve(__int64 x)
{
  int p = binsearch(x);
  if(b[p+1] == -1)
    return a[p+1];
  __int64 v = (x-f[p]) % a[p+1];
  if(v == 0)
    v = a[p+1];
  return solve(v);
}
int main()
{
   scanf("%d", &n);
   for(int i=1; i<=n; i++)
     {
        scanf("%d", &k);
        if(k == 1)
          {
             scanf("%d", &a[i]);
             b[i] = -1;
             f[i] = f[i-1] + 1;
          }
        else
          {
             scanf("%d %d", &a[i], &b[i]);
             f[i] = f[i-1] + a[i]*b[i];
          }
     }
   __int64 x;
   scanf("%d", &m);
   for(int i=1; i<=m; i++)
     {
        scanf("%I64d", &x);
        ans[i] = solve(x);
     }
   printf("%d", ans[1]);
   for(int i=2; i<=m; i++)
     printf(" %d", ans[i]);
   puts("");
   return 0;
}

    
    


C

题意:输入一个字符串, 然后实现m次操作, 每次操作输入了l, r, 要求输出该区间内最大的正确括号长度

思路:采用线段树, 节点维护三个域,正确括号数,未匹配左括号数, 未匹配右括号数

#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
using namespace std;

typedef struct
{
 int s, l, r;
}node;
node a[1000010*4];
char s[1000010];
int ql, qr, n, m;
void construct(int o, int l, int r)
{
   if(l == r)
    {
      a[o].s = 0;
      if(s[l] == '(')
      	a[o].l = 1;
      else
      	a[o].r = 1;
      return;
    }
   int m = (l+r) / 2;
   construct(2*o, l, m);
   construct(2*o+1, m+1, r);
   a[o].s = a[2*o].s + a[2*o+1].s + min(a[2*o].l, a[2*o+1].r);
   a[o].l = a[2*o].l + a[2*o+1].l - min(a[2*o].l, a[2*o+1].r);
   a[o].r = a[2*o].r + a[2*o+1].r - min(a[2*o].l, a[2*o+1].r);
}
void query(int o, int l, int r, int &v1, int &v2, int &v3)
{
  if(ql<=l && qr>=r)
    {
      v1 = a[o].l, v2 = a[o].r, v3 = a[o].s;
      return;
    }
  if(ql>r || qr
       
       
      
      
     
     
    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值