Error in segment tree with lazy propagation - c++11

This is the problem of the SPOJ "SEGSQRSS - Sum of Squares with Segment Tree" the link to the problem is http://www.spoj.com/problems/SEGSQRSS/ I'm trying to do it using lazy propagation but cannot find the correct solution, can anyone help where I'm going wrong.
#include <map>
#include <set>
#include <math.h>
#include <string>
#include <vector>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define inf 0x7fffffff
#define mod 1000000007
#define ll long long int
#define all(c) c.begin(),c.end()
#define tr(c,i) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
// it uses lazy propagation
struct seg
{
ll x;// which stores the value of the 2*(sum of the elements of the segment)
ll sum;// stores the sum of the square of the elements of the segment
};
seg tree[2000050];
ll arr[100005],lazyadd[2000050],lazycha[2000050];
ll query_tree(ll node,ll a,ll b,ll i,ll j);
void build_tree(ll node,ll a,ll b);
void build_tree(ll node,ll a,ll b)
{
if(a>b)return ;
if(a==b)
{
tree[node].x=2*arr[a];
tree[node].sum=arr[a]*arr[a];
return ;
}
build_tree(2*node,a,a+((b-a)/2));
build_tree(2*node+1,1+a+((b-a)/2),b);
tree[node].x=tree[2*node].x+tree[2*node+1].x;
tree[node].sum=tree[2*node].sum+tree[2*node+1].sum;
return ;
}
ll query_tree(ll node,ll a,ll b,ll i,ll j)
{
if(a > b || a > j || b < i) return 0;
ll ans;
ll mid=(a+b)/2;
if((lazyadd[node]!=0)||(lazycha[node]!=0))
{
// this is for type 0
if(i!=j){
if(lazycha[node]!=0){
tree[2*node].sum=(mid-a+1)*lazycha[node]*lazycha[node];
tree[2*node].x=(mid-a+1)*lazycha[node]*2;
tree[2*node+1].sum=(b-mid)*lazycha[node]*lazycha[node];
tree[2*node+1].x=(b-mid)*lazycha[node]*2;
lazycha[2*node]=lazycha[2*node]+lazycha[node];
lazycha[2*node+1]=lazycha[2*node+1]+lazycha[node];
}
// this is for type 1
if(lazyadd[node]!=0){
tree[2*node].sum=tree[2*node].sum+tree[2*node].x*lazyadd[node]+(mid-a+1)*lazyadd[node]*lazyadd[node];
tree[2*node].x=tree[2*node].sum+(mid-a+1)*lazyadd[node]*2;
tree[2*node+1].sum=tree[2*node+1].sum+tree[2*node+1].x*lazyadd[node]+(b-mid)*lazyadd[node]*lazyadd[node];
tree[2*node+1].sum=tree[2*node+1].sum+(b-mid)*lazyadd[node]*2;
lazyadd[2*node]=lazyadd[2*node]+lazyadd[node];
lazyadd[2*node+1]=lazyadd[2*node+1]+lazyadd[node];
}
}
lazyadd[node]=0;
lazycha[node]=0;
}
if((i<=a)&&(b<=j))return tree[node].sum;
ll ans1=query_tree(2*node,a,a+((b-a)/2),i,j);
ll ans2=query_tree(2*node+1,a+((b-a)/2)+1,b,i,j);
ans=ans1+ans2;
return ans;
}
void update_tree(ll node,ll a,ll b,ll i,ll j,ll value,ll type)
{
if(a > b || a > j || b < i) return ;
ll mid=(a+b)/2;
if((lazyadd[node]!=0)||(lazycha[node]!=0))
{
// this is for type 0
if(i!=j){
if(lazycha[node]!=0){
tree[2*node].sum=(mid-a+1)*lazycha[node]*lazycha[node];
tree[2*node].x=(mid-a+1)*lazycha[node]*2;
tree[2*node+1].sum=(b-mid)*lazycha[node]*lazycha[node];
tree[2*node+1].x=(b-mid)*lazycha[node]*2;
lazycha[2*node]=lazycha[2*node]+lazycha[node];
lazycha[2*node+1]=lazycha[2*node+1]+lazycha[node];
}
// this is for type 1
if(lazyadd[node]!=0){
tree[2*node].sum=tree[2*node].sum+tree[2*node].x*lazyadd[node]+(mid-a+1)*lazyadd[node]*lazyadd[node];
tree[2*node].x=tree[2*node].sum+(mid-a+1)*lazyadd[node]*2;
tree[2*node+1].sum=tree[2*node+1].sum+tree[2*node+1].x*lazyadd[node]+(b-mid)*lazyadd[node]*lazyadd[node];
tree[2*node+1].sum=tree[2*node+1].sum+(b-mid)*lazyadd[node]*2;
lazyadd[2*node]=lazyadd[2*node]+lazyadd[node];
lazyadd[2*node+1]=lazyadd[2*node+1]+lazyadd[node];
}
}
lazyadd[node]=0;
lazycha[node]=0;
}
if((i<=a)&&(b<=j))
{
if(type==0)
{
tree[node].sum=(b-a+1)*value*value;
tree[node].x=(b-a+1)*value*2;
lazycha[node]+=value;
return;
}
else if(type==1)
{
tree[node].sum=tree[node].sum+tree[node].x*value+(b-a+1)*value*value;
tree[node].x+=(b-a+1)*value*2;
lazyadd[node]+=value;
return;
}
}
update_tree(2*node,a,a+((b-a)/2),i,j,value,type);
update_tree(2*node+1,1+a+((b-a)/2),b,i,j,value,type);
tree[node].sum=tree[2*node].sum+tree[2*node+1].sum;
}
int main()
{
ll t,x,n,c,i,j,v;
cin>>t;
for(x=1;x<=t;x++){
memset(lazyadd,0,sizeof(lazyadd));
memset(lazycha,0,sizeof(lazycha));
ios_base::sync_with_stdio(0);//this is the boost :)
scanf("%lld%lld",&n,&c);
for(i=1;i<=n;i++)scanf("%lld",&arr[i]);//cin>>arr[i];
build_tree(1,1,n);
cout<<"Case "<<x<<endl;
while(c--)
{
int type;
scanf("%d",&type);
if(type==2)
{
scanf("%lld%lld",&i,&j);
printf("%lld\n",query_tree(1,1,n,i,j));
}
else
{
scanf("%lld%lld%lld",&i,&j,&v);
update_tree(1,1,n,i,j,v,type);
}
}
}
return 0;
}
Thanks in Advance.

Related

how can we add an element in the map of set...eg .map<int,unordered_multiset<int>>mp; in c++14

i want add an element to the mp[x].
map<int,unordered_multiset>adj;
for(int i=0;i<n;i++)
{
cin>>brr[i];
if(brr[i]!=arr[i])
{
// i want to add an element
//in mp[brr[i]] ;
}
else
{
comp.insert({brr[i],i+1}); //set
}
}
}
Here is an example for a map from int to unordered_multiset<int>.
#include <map>
#include <unordered_set>
#include <iostream>
int main() {
std::map<int, std::unordered_multiset<int>> adj;
const int z = 10;
adj[6].insert(z);
adj[6].insert({1,2,3});
auto& myset = adj[6];
for(auto const& x : myset) {
std::cout << x << std::endl;
}
return 0;
}
Output:
3
2
1
10
The examples on cppreference are usually quite good:
https://en.cppreference.com/w/cpp/container/map#Example
https://en.cppreference.com/w/cpp/container/map/insert#Example
And then you have to find the correct way to insert into the multiset:
https://en.cppreference.com/w/cpp/container/unordered_multiset/insert
And one of them uses the initializer_list {}

STD::FUNCTION C++

I'm still learning Modern C++ and I would like to clarify STD:FUNCTION,
Here is my sample code that works fine :
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()() {
return true;
}
};
int main() {
cout << func(fee());
}
It will display "2" on the console.
What I am wondering is why this does not work. I changed bool operator()() to bool operator()(int i).
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()(int i) {
return true;
}
};
int main() {
cout << func(fee());
}
The error says:
In function 'int main()':
18:20: error: could not convert 'fee()' from 'fee' to 'std::function<bool()>'
What should be the right thing to do ?
In the second example, the fee operator() function now takes an int as a parameter.
Therefore you need to change
int func(function<bool()> foo) {
return 2;
}
to
int func(function<bool(int)> foo) {
return 2;
}
to reflect that.

Extract IP from text file C++

Im a new programmer in C++ and I want to creat a code that extract IP from text files
I tried to convert txt file to Vector(string) to be easy filtering but i cant get all formes like XXX.XXX.XXX.XXX
Given that the ip could be embedded in some text, we'll parse the string and fetch it.
#include <iostream>
#include <string>
#include <iterator>
#include <vector>
#include <sstream>
using namespace std;
string ip(string str)
{
//middle portion
auto firstDot = str.find_first_of('.');
auto lastDot = str.find_last_of('.');
int dotCount = 0;
for(auto i = firstDot; i <= lastDot; i++)
{
if(!isdigit(str.at(i)) && str.at(i) != '.') //e.g 127.ss.0y.1
return string("");
if(str.at(i) == '.')
dotCount++;
}
if(dotCount != 3) //eg. 127.0.1 (not sure if this is wrong though)
return string("");
string result = str.substr(firstDot,lastDot-firstDot + 1);
//left portion
size_t x = 0; //number consegative digits from the first dot
for(auto i = firstDot-1; i >= 0; i--)
{
if(!isdigit(str.at(i)))
break;
else if(x == 3) //take first 3
break;
x++;
}
if(x == 0)
return string("");
result.insert(0,str.substr(firstDot-x,x));
//right portion
size_t y = 0;
for(auto i = lastDot + 1; i < str.length(); i++)
{
if(isdigit(str.at(i)))
{
if(y == 3)
break;
result.push_back(str.at(i));
y++;
}
else
break;
}
if(y == 0)
result.push_back('0');
return result;
}
int main()
{
string test = "1111127.0.0.11111 xx23.45.12.# xxxx.34.0.13 124.sd.2.1 sd.45.56.1";
string x,y;
vector<string> ips;
stringstream stream;
stream<<test;
while(stream>>x)
if(!(y = ip(x)).empty())
ips.push_back(y);
for(auto z : ips)
cout<<z<<"\t";
cout<<endl;
system("pause");
return 0;
}
#include<iostream>
#include<fstream>
using namespace std;
int main() {
ifstream myReadFile;
myReadFile.open("text.txt");
char output[100];
if (myReadFile.is_open()) {
while (!myReadFile.eof()) {
myReadFile >> output;
cout<<output;
}
}
myReadFile.close();
return 0;
}
Use this if the text file only includes IP's on each line.
Or depending on what c++ you're using:
std::ifstream file("Read.txt");
std::string str;
std::string file_contents;
while (std::getline(file, str))
{
file_contents += str;
file_contents.push_back('\n');
}
I'm new to C++11. I did the following simple example for you. It's based on the regex library. Hope it works for you!
#include <iostream>
#include <string>
#include <regex>
int main ()
{
std::string s ("There's no place like 127.0.0.1\n");
std::smatch m;
std::regex e ("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
while (std::regex_search (s,m,e)) {
for (auto x:m) std::cout << x << " ";
std::cout << std::endl;
s = m.suffix().str();
}
return 0;
}

boost::variant vs. polymorphism, very different performance results with clang and gcc

I'm trying to figure out how much the execution time of boost::variant differ from a polymorphism approach. In my first test I got very different results on gcc 4.9.1 and clang+llvm 3.5.
You can find the code below. Here are my results:
clang+llvm
polymorphism: 2.16401
boost::variant: 3.83487
gcc:
polymorphism: 2.46161
boost::variant: 1.33326
I compiled both with -O3.
Is someone able to explain that?
code
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <ctime>
struct value_type {
value_type() {}
virtual ~value_type() {}
virtual void inc() = 0;
};
struct int_type : value_type {
int_type() : value_type() {}
virtual ~int_type() {}
void inc() { value += 1; }
private:
int value = 0;
};
struct float_type : value_type {
float_type() : value_type() {}
virtual ~float_type() {}
void inc() { value += 1; }
private:
float value = 0;
};
void dyn_test() {
std::vector<std::unique_ptr<value_type>> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(new int_type());
else
v.emplace_back(new float_type());
}
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), [](auto &item) { item->inc(); });
}
}
struct visitor : boost::static_visitor<> {
template <typename T> void operator()(T &item) { item += 1; }
};
using mytype = boost::variant<int, float>;
void static_test() {
std::vector<mytype> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(0);
else
v.emplace_back(0.f);
}
visitor vi;
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), boost::apply_visitor(vi));
}
}
template <typename F> double measure(F f) {
clock_t start = clock();
f();
clock_t end = clock();
float seconds = (float)(end - start) / CLOCKS_PER_SEC;
return seconds;
}
int main() {
std::cout << "polymorphism: " << measure([] { dyn_test(); }) << std::endl;
std::cout << "boost::variant: " << measure([] { static_test(); }) << std::endl;
return 0;
}
assembler
gcc
clang+llvm
Clang is known to miscompile some std::vector functions from various Standard libraries, due to some edge cases in their inliner. I don't know if those have been fixed by now but quite possibly not. Since unique_ptr is smaller and simpler than boost::variant it's more likely that it does not trigger these edge cases.
The code you post is practically "Why boost::variant is great". A dynamic allocation and random pointer index in addition to the regular indirections that both perform? That's a heavy hit (relatively).

Difficulty in Implementation in Segment tree with lazy propogation

I am having trouble in implementing segment tree with lazy propagation. I just read about segment trees and tried to do a simple question (http://www.codechef.com/problems/FLIPCOIN) using it but I am getting wrong answer. Please help me with the implementation. Here is my code(If you prefer ideone:http://ideone.com/SHVZ5y):
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility>
#include <map>
#include <vector>
#include <list>
#include <string>
#include <set>
#include <queue>
#define s(x) scanf("%d",&x)
#define sil(x) scanf("%llu",&x)
#define sd(x) scanf("%ld",&x)
#define FOR(i,a,b) for( typeof(a) i=(a); i<(b); ++i) // exclusive for
#define FORR(i,a,b) for( typeof(a) i=(a-1) ; i>=(b); --i)
#define REP(k,a,b) for(typeof(a) k=(a); k <= (b); ++k) // inclusive for
#define REPR(i,a,b) for( typeof(a) i=(a) ; i>=(b); --i)
#define ALL(c) (c).begin(), (c).end()
#define PB push_back
#define MP make_pair
#define SZ(x) ((int)((x).size()))
#define SRT(v) std::sort(ALL(v))
#define CTN(x) std::cout<<x<<'\n' //cout with newline
#define CTS(x) std::cout<<x<<" " //cout with space
#define CLR(x) std::memset(x,0,sizeof(x))
#define FILL(x,n) std::fill_n(x,sizeof(x),n)
#define DBGA(x,n) {FOR(i,0,n) cout<<x[i]<<" "; CTN(" ");}
//#define NL printf("\n")
typedef std::vector<int> VI;
typedef std::vector<long long int> VL;
typedef std::vector<std::string> VS;
typedef std::map<int,int> MI;
typedef std::pair<int,int> PII;
typedef unsigned long long ull;
typedef long long ll;
using namespace std;
struct node{
int h; //number of head
int t; //number of tail
int lazy;
node()
{
h=0;
t=0;
lazy=0;
}
}tree[300000];
void build_tree(int n,int a,int b)
{
//cout<<"wo"<<endl;
if(a>b)
return;
if(a==b)
{
tree[n].h=0;
tree[n].t=1;
//cout<<tree[n]<<" "<<a<<" "<<b<<" "<<n<<endl;
return;
}
build_tree(2*n+1,a,(a+b)/2);
build_tree(2*n+2,(a+b)/2+1,b);
tree[n].t=tree[2*n+1].t+tree[2*n+2].t;
//cout<<tree[n]<<" "<<a<<" "<<b<<" "<<n<<endl;
}
int query(int n,int ql,int qr,int l,int r)
{
if(tree[n].lazy!=0)
{
int tmp=tree[n].h;
tree[n].h=tree[n].t;
tree[n].t=tmp;
if(r!=l)
{
tree[2*n+1].lazy=1;
tree[2*n+2].lazy=1;
}
tree[n].lazy=0;
}
if(l>qr || r<ql)
return 0;
if(l>=ql && r<=qr)
return tree[n].h;
return query(2*n+1,ql,qr,l,(l+r)/2)+query(2*n+2,ql,qr,(l+r)/2+1,r);
}
void update(int n,int ul,int ur,int l,int r)
{
if(tree[n].lazy!=0)
{
int tmp=tree[n].h;
tree[n].h=tree[n].t;
tree[n].t=tmp;
if(r!=l)
{
tree[2*n+1].lazy=1;
tree[2*n+2].lazy=1;
}
tree[n].lazy=0;
}
if(l>ur || r<ul)
return ;
if(l>=ul && r<=ur)
{
int tmp=tree[n].h;
tree[n].h=tree[n].t;
tree[n].t=tmp;
if(r!=l)
{
tree[2*n+1].lazy=1;
tree[2*n+2].lazy=1;
}
return;
}
update(2*n+1,ul,ur,l,(l+r)/2);
update(2*n+2,ul,ur,(l+r)/2+1,r);
tree[n].h=tree[2*n+1].h+tree[2*n+2].h;
tree[n].t=tree[2*n+1].t+tree[2*n+2].t;
}
int main()
{
std::ios_base::sync_with_stdio(false);
int n;cin>>n;
build_tree(0,0,n-1);
int q;cin>>q;
while(q--)
{
int t;cin>>t;int l,r;cin>>l>>r;
if(t)
{
cout<<query(0,l,r,0,n-1)<<'\n';
}
else
{
update(0,l,r,0,n-1);
/*CTN(" ");
FOR(i,0,7)
cout<<i<<" "<<tree[i].h<<'\n';
CTN(" ");*/
}
}
}
There was a problem with the lazy propagation part. It should be:
tail[2*n+1].lazy=1-tail[2*n+1].lazy
and not
tail[2*n+1].lazy=1

Resources