SPOJ-与勇气一起生活片段树
SPOJ - Living with Courage Segment Tree
这是问题链接-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上制作了我的程序,并提交了两种类型的解决方案:
- 当我没有检查苹果的数量是正数还是负数时
- 当我检查苹果的数量是正数还是负数时
有趣的部分都被接受了。如果你想看看我的解决方案,这里是链接=>解决方案以下是我如何修改你的代码:
#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);
}
}
相关文章:
- 宽度为奇数的16位纹理为片状
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- Opengl 3.1 GLSL 140 在 C++ 年输出白色在片段着色器中
- 这两个代码片段相似,但显示的结果不同
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- 我需要解释给定片段的输出
- 如果我在下面的代码片段中添加"delete[] d;",为什么我得到零?
- 我遇到了这个代码片段,不明白. 它递归检查 C++ 字符串中是否存在大写字符
- 任何人都可以解释一下我是否需要 & 在第一个代码片段中
- OpenGL 片段着色器未在英特尔 HD 4000 显卡上编译
- 帧缓冲纹理变为白色(片段着色器不会影响它)
- 如何在 c++ 中检查连续片段中数字被 11 整除
- 玉米片实验中"*"标记之前的预期初始值设定项
- 提取狮身人面像文档中的C++代码片段
- 为什么此代码片段有效?如何取消引用空点?
- 将顶点位置从顶点传递到片段着色器 - 仅在使用 Nsight 进行调试时有效
- 无法在这个基本的Qt代码片段中找到错误,但我被告知它肯定存在?
- 使用片段着色器写入 1D 纹理后从 1D 纹理读回不起作用
- 如何在顶点着色器中使用VBO数据作为位置数据,在片段着色器中使用统一数据作为颜色数据
- SPOJ-与勇气一起生活片段树