SPOJ-与勇气一起生活片段树

SPOJ - Living with Courage Segment Tree

本文关键字:生活片 片段 生活 一起 勇气 SPOJ-      更新时间:2023-10-16

这是问题链接-http://www.spoj.com/problems/COURAGE/

我的代码给出了WA。我用seg[]表示段和树,用seg2[]表示段最小树。我做sum(range)-min(range)来根据问题输出一个范围内的计数。

#include <iostream>
#include <string>
#include <climits>
using namespace std;
long long int apples[100020],seg[200022],seg2[200022];
long long int min (long long int a, long long int b){
    if(a<b) return a;
    return b;
}
void buildt(long long int start,long long int end,long long int node){    
    if(start == end){
       seg[node] = apples[start];   
       seg2[node] = apples[start];
   }
   else{
       long long int mid = (long long int) ((start + end) / 2);
        buildt( start, mid,(long long int)(2*node));
        buildt( (long long int)(mid+1), end,(long long int)((2*node)+1));
        seg[node] = seg[2*node] + seg[(2*node)+1];
        seg2[node] = min(seg2[2*node] , seg2[(2*node)+1]);
    }    
}
void update(long long int node,long long int start,long long int end,long long int idx, long long int val)
{
   if(start == end )
   {
       apples[idx] = (long long int) (apples[idx] +  val);
       if(apples[idx] < 0){
           seg[node] = 0;
           seg2[node] = 0;
       }
       else{
       seg[node]  = (long long int)(seg[node]+ val);
       seg2[node] = (long long int)(seg2[node] + val);
       }
    }
    else
    {
        long long int mid = (long long int) ((start + end) / 2);
        if(start <= idx && idx <= mid)        
            update( (long long int)(2*node), start, mid, idx, val);        
        else
           update((long long int)((2*node)+1), (long long int)(mid+1), end, idx, val);
        seg[node] = seg[2*node] + seg[(2*node)+1];
       seg2[node] = min(seg2[2*node] , seg2[(2*node)+1]);
   }
}
long long int querysum(long long int node, long long int start, long long int end,long long int l,long long int r)
{ 
   if(r < start || end < l)
   {
       return 0;
    }
  if(l <= start && end <= r)
      return seg[node];
  long long int mid = (long long int) ((start + end) / 2);
  long long int p1 = querysum((long long int)(2*node), start, mid, l, r);
  long long int p2 = querysum((long long int)((2*node)+1), (long long int)(mid+1), end, l, r);
  return (p1 + p2);
}
long long int querymin(long long int node, long long int start, long long int end, long long int l, long long int r)
{
   if(r < start || end < l)
   {
       return LLONG_MAX;
   }
   if(l <= start && end <= r)
      return seg2[node];
  long long int mid = (long long int) ((start + end) / 2);
  long long int p1 = querymin((long long int)(2*node), start, mid, l, r);
  long long int p2 = querymin((long long int)((2*node)+1), (long long int)(mid+1), end, l, r);
  return min(p1 , p2);
}
int main()
{
   long long int n;
   cin >> n;
   for(int i = 1; i <= n; i++)
      cin >> apples[i];
  buildt(1,n,1);
  int op;
  cin >> op;
      string c;
      getline(cin,c);
  while(op--){
      cin >> c;
       char a1[64];
       char a2[64];
       cin >> a1 >> a2;
       if(c[0] == 'C')           
            cout <<  querysum(1,1,n,(long long int)(atoll(a1)+1),(long long int)(atoll(a2)+1)) -  querymin(1,1,n,(long long int)(atoll(a1)+1),(long long int)(atoll(a2)+1))<<endl;        
        else 
          if(c[0] == 'G')
             update(1,1,n,(long long int)(atoll(a2)+1),(long long int)(atoll(a1)));
          else
             update(1,1,n,(long long int)(atoll(a2)+1),(long long int)(-1*(atoll(a1))));  
        }          
}

我对C++了解不多,我在spoj C++(g++4.3.2)上运行您的代码它给了我编译错误。然后我根据自己的舒适度对它进行了修改,它给了我SIGSEGV。(不过它在ideone上运行良好)。

现在关于问题:当苹果的数量变为负数时(勇气吃的苹果比可用的多),您可以使特定节点上的苹果数量等于0(零)。这是你的代码部分:

if(start == end )
   {
       apples[idx] = (long long int) (apples[idx] +  val);
       if(apples[idx] < 0){
           seg[node] = 0;
           seg2[node] = 0;
       }
       else{
       seg[node]  = (long long int)(seg[node]+ val);
       seg2[node] = (long long int)(seg2[node] + val);
       }
    }

您使seg[node]=seg2[node]=0,但我认为您忘记将apple[node]修改为0。所以我认为正确的逻辑是:

if(start == end )
   {
       apples[idx] = (long long int) (apples[idx] +  val);
       if(apples[idx] < 0){
           apples[idx]=0;
           seg[node] = 0;
           seg2[node] = 0;
       }
       else{
       seg[node]  = (long long int)(seg[node]+ val);
       seg2[node] = (long long int)(seg2[node] + val);
       }
    }

我在java上制作了我的程序,并提交了两种类型的解决方案:

  1. 当我没有检查苹果的数量是正数还是负数时
  2. 当我检查苹果的数量是正数还是负数时

有趣的部分都被接受了。如果你想看看我的解决方案,这里是链接=>解决方案以下是我如何修改你的代码:

    #include <iostream>
#include <string>
#include <climits>
using namespace std;
long long int apples[100020],seg[200022],seg2[200022];
long long int min (long long int a, long long int b){
    if(a<b) return a;
    return b;
}
void buildt(long long int start,long long int end,long long int node){
    if(start == end){
       seg[node] = apples[start];
       seg2[node] = apples[start];
   }
   else{
       long long int mid = (long long int) ((start + end) / 2);
        buildt( start, mid,(long long int)(2*node));
        buildt( (long long int)(mid+1), end,(long long int)((2*node)+1));
        seg[node] = seg[2*node] + seg[(2*node)+1];
        seg2[node] = min(seg2[2*node] , seg2[(2*node)+1]);
    }
}
void update(long long int node,long long int start,long long int end,long long int idx, long long int val)
{
   if(start == end )
   {
       apples[idx] = (long long int) (apples[idx] +  val);
       if(apples[idx] < 0){
           apples[idx]=0;
           seg[node] = 0;
           seg2[node] = 0;
       }
       else{
       seg[node]  = (long long int)(seg[node]+ val);
       seg2[node] = (long long int)(seg2[node] + val);
       }
    }
    else
    {
        long long int mid = (long long int) ((start + end) / 2);
        if(start <= idx && idx <= mid)
            update( (long long int)(2*node), start, mid, idx, val);
        else
           update((long long int)((2*node)+1), (long long int)(mid+1), end, idx, val);
        seg[node] = seg[2*node] + seg[(2*node)+1];
       seg2[node] = min(seg2[2*node] , seg2[(2*node)+1]);
   }
}
long long int querysum(long long int node, long long int start, long long int end,long long int l,long long int r)
{
   if(r < start || end < l)
   {
       return 0;
    }
  if(l <= start && end <= r)
      return seg[node];
  long long int mid = (long long int) ((start + end) / 2);
  long long int p1 = querysum((long long int)(2*node), start, mid, l, r);
  long long int p2 = querysum((long long int)((2*node)+1), (long long int)(mid+1), end, l, r);
  return (p1 + p2);
}
long long int querymin(long long int node, long long int start, long long int end, long long int l, long long int r)
{
   if(r < start || end < l)
   {
       return LLONG_MAX;
   }
   if(l <= start && end <= r)
      return seg2[node];
  long long int mid = (long long int) ((start + end) / 2);
  long long int p1 = querymin((long long int)(2*node), start, mid, l, r);
  long long int p2 = querymin((long long int)((2*node)+1), (long long int)(mid+1), end, l, r);
  return min(p1 , p2);
}
int main()
{
   long long int n;
   cin >> n;
   for(int i = 1; i <= n; i++)
      cin >> apples[i];
  buildt(1,n,1);
  int op;
  cin >> op;
      string c;
      getline(cin,c);
  while(op--){
      cin >> c;
       long long a1,a2;
       cin >> a1 >> a2;
       if(c[0] == 'C')
            cout <<  querysum(1,1,n,a1+1,a2+1) -  querymin(1,1,n,a1+1,a2+1)<<endl;
        else
          if(c[0] == 'G')
             update(1,1,n,a2+1,a1);
          else
             update(1,1,n,a2+1,0-a1);
        }
}