Incorrect update elements in Fenwick Tree - fenwick-tree

I wrote a program, which give an sum of range by getting command 's' and update an element by command 'u', but it works incorrect.
Help me please.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
template <typename indexT, typename valueT> class FenwickTree{
public:
FenwickTree(vector<valueT> &buffer){
tree.resize(buffer.size());
for (indexT i = 0; i < buffer.size(); ++i)
update(i, buffer[i]);
}
valueT getSolution(const indexT l, const indexT r) const{
return getSolution(r) - getSolution(l - 1);
}
void update(indexT position, const valueT v){
valueT delta = v - tree[position];
for (indexT i = position; i < tree.size(); i = i | (i + 1))
tree[i] += delta;
}
private:
vector <valueT> tree;
valueT getSolution(const indexT r) const{
valueT result = 0;
for (indexT i = r; i >= 0; i = (i & (i + 1)) - 1)
result = tree[i] + result;
return result;
}
};
int main(){
ifstream file;
file.open("D:\\input.txt", ios::in);
unsigned long long n, k;
file >> n;
vector<long long> buffer(n);
for (long long i = 0; i < n; ++i)
file >> buffer[i];
file >> k;
FenwickTree<long long, long long> fenwickTree(buffer);
for (long long i = 0; i < k; ++i){
char command;
long long a, b;
file >> command >> a >> b;
if (command == 's')
cout << fenwickTree.getSolution(a - 1, b - 1) << " ";
else if (command == 'u')
fenwickTree.update(a - 1, b);
}
file.close();
return 0;
}
Correct work:
input:
10
613 263 312 670 216 142 976 355 488 370
10
s 2 7
s 4 8
u 7 969
u 1 558
s 2 7
u 2 731
s 4 9
s 1 3
u 8 76
u 5 377
output:
2579 2359 2572 2840 1601
I calculate a delta between new old and new value and then update fenwick tree, but it doesn't work for me.

Fixed it:
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
template <typename indexT, typename valueT> class FenwickTree{
public:
FenwickTree(vector<valueT> &buffer){
tree.resize(buffer.size());
for (indexT i = 0; i < buffer.size(); ++i)
update(i, buffer[i]);
}
valueT getSolution(const indexT l, const indexT r) const{
return getSolution(r) - getSolution(l - 1);
}
void update(indexT position, const valueT v){
for (indexT i = position; i < tree.size(); i = i | (i + 1))
tree[i] += v;
}
private:
vector <valueT> tree;
valueT getSolution(const indexT r) const{
valueT result = 0;
for (indexT i = r; i >= 0; i = (i & (i + 1)) - 1)
result += tree[i];
return result;
}
};
int main(){
ifstream file;
file.open("D:\\input.txt", ios::in);
unsigned long long n, k;
file >> n;
vector<long long> buffer(n);
for (long long i = 0; i < n; ++i)
file >> buffer[i];
file >> k;
FenwickTree<long long, long long> fenwickTree(buffer);
for (long long i = 0; i < k; ++i){
char command;
long long a, b;
file >> command >> a >> b;
if (command == 's')
cout << fenwickTree.getSolution(a - 1, b - 1) << " ";
else if (command == 'u'){
fenwickTree.update(a - 1, b - buffer[a - 1]);
buffer[a - 1] = b;
}
}
file.close();
int lal = 0;
cin >> lal;
return 0;
}

Related

Wrong output in large inputs

Please help me out with this problem: https://cses.fi/problemset/task/1131/
I'm getting the wrong output for large values.
The algorithm is: computing the height of the left subtree and the right subtree by using an arbitrary node.
Thank you :)
#include <bits/stdc++.h>
#define int long long int
using namespace std;
bool visited[200005] = {false};
vector<vector<int>> vect(200005);
int height(int n) {
int m = 0, t=-1;
visited[n] = true;
for(auto x : vect[n]) {
if(visited[x] == false) {
t = height(x);
if(m < t)
m = t;
}
}
return m+1;
}
int treeDiameter(int n) {
int m1=0, m2=0, t=0;
visited[n] = true;
for(auto x : vect[n]) {
t = height(x);
if(t > m1) {
m2 = m1;
m1 = t;
}
else if(t > m2)
m2 = t;
}
return m1 + m2;
}
int32_t main() {
int n, m=999999;
cin >> n;
n--;
if(n > 1) {
while(n--) {
int a, b;
cin >> a >> b;
vect[a].push_back(b);
vect[b].push_back(a);
if(a < m) m = a;
}
// cout << m;
cout << treeDiameter(m);
} else cout << 0 << endl;
return 0;
}

Prim Algorithm application

everyone, I have a weighted connected undirected graph, I need to find it's minimum spanning tree weight. On input I have numbers n(vertices amount), m(edges amount). And then m edges in format: A(out vert), B(in vert), C(weight). Here is input example:
3 3
1 2 1
2 3 2
3 1 3
I see it as a typical Prim algorithm, so I used it, but some tests are telling me that my code gives a wrong answer. Here it is:
#include <numeric>
#include <iostream>
using namespace std;
long long primAlgo(const int vertices, const vector<vector<long long>> &edges) {
vector<bool> visited(vertices, false);
vector<long long> minimal(vertices, 30001);
minimal[0] = 0;
for (size_t i = 0; i != vertices; ++i) {
int vert = -1;
for (size_t option = 0; option != vertices; ++option) {
if (!visited[option] && (vert == -1 || minimal[option] < minimal[vert]))
vert = option;
}
visited[vert] = true;
for (size_t to = 0; to != vertices; ++to) {
if (edges[vert][to] < minimal[to]) {
minimal[to] = edges[vert][to];
}
}
}
long long sum = 0;
for (size_t i = 0; i != vertices; ++i) {
sum += minimal[i];
}
return sum;
}
int main() {
int n, m;
cin >> n >> m;
int A, B;
long long C;
vector<vector<long long>> l(n, vector<long long> (n, 30001));
for (size_t i = 0; i != m; ++i) {
cin >> A >> B >> C;
l[A - 1][B - 1] = C;
l[B - 1][A - 1] = C;
}
long long ans = primAlgo(n, l);
cout << ans;
}
So I was wondering, if you know, what the problem may be.

Fibonacci Number modulo m

Task: Given two integers n and m, output Fn mod m (they is, the remainder of Fn when divided by m).
My Code:
#include <iostream>
#include <vector>
using namespace std;
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c;
for (int i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
}
long long calc_fib(long long n)
{
vector<long long> nums(n + 1);
nums.at(0) = 0;
nums.at(1) = 1;
for (long long i = 2; i < nums.size(); i++)
{
nums.at(i) = nums.at(i - 1) + nums.at(i - 2);
}
return nums.at(n);
}
long long solve(long long n, long long m)
{
long long r = n % get_pisano_period(m);
return (calc_fib(r) % m);
}
int main()
{
long long n, m;
cin >> n >> m;
cout << solve(n, m) << endl;
return 0;
}
My code is working for some cases(small numbers). Can anyone suggest to me, What changes should I make to run this?
Input:
239
1000
Output:
-191
You can see I am supposed to get 161 as output.
I tried what #idclev463035818 said and this seems to work.
Try it,
# include <iostream>
# include <vector>
using namespace std;
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c;
for (long long i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
}
long long calc_fib(long long n, long long m)
{
vector<long long> nums(n + 1);
nums.at(0) = 0;
nums.at(1) = 1;
long long maximum = get_pisano_period(m);
for (long long i = 2; i < nums.size(); i++)
{
nums.at(i) = (nums.at(i - 1)%m + nums.at(i - 2)%m)%m;
}
return nums.at(n);
}
int main()
{
long long n, m;
cin >> n >> m;
cout << calc_fib(n, m) << endl;
return 0;
}

Perceptron Model in C++ not Converging

So I was writing a simple Perceptron model and when I finished the code and saw that there were no errors I was pretty surprised. But it seems like my model doesn't converge (along with some other oddities).
Basically it keeps getting 25/100 samples right at every epoch. And when every epoch ends the weights are always coming back to 0.
Due to the fact that the code is on multiple files I put it on Google Drive here it is:
https://drive.google.com/folderview?id=0B_r3mf9HbUrLaDNlc1F6RXhNMnM&usp=sharing
It is a Visual Studio Community 2013 project. You can open and run it so that you get a better idea.
Here's a quick preview of the files though.
main.cpp:
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
#include <string>
#include <math.h>
#include "LinearAlgebra.h"
#include "MachineLearning.h"
using namespace std;
using namespace LinearAlgebra;
using namespace MachineLearning;
void printVector(vector< vector<float> > X);
vector< vector<float> > getIrisX();
vector<float> getIrisy();
int main()
{
vector< vector<float> > X = getIrisX();
vector<float> y = getIrisy();
vector<float> test1;
test1.push_back(5.0);
test1.push_back(3.3);
test1.push_back(1.4);
test1.push_back(0.2);
vector<float> test2;
test2.push_back(6.0);
test2.push_back(2.2);
test2.push_back(5.0);
test2.push_back(1.5);
//printVector(X);
//for (int i = 0; i < y.size(); i++){ cout << y[i] << " "; }cout << endl;
perceptron clf(0.1, 10);
clf.fit(X, y);
cout << "Now Predicting: 5.0,3.3,1.4,0.2(CorrectClass=1,Iris-setosa) -> " << clf.predict(test1) << endl;
cout << "Now Predicting: 6.0,2.2,5.0,1.5(CorrectClass=-1,Iris-virginica) -> " << clf.predict(test2) << endl;
system("PAUSE");
return 0;
}
void printVector(vector< vector<float> > X)
{
for (int i = 0; i < X.size(); i++)
{
for (int j = 0; j < X[i].size(); j++)
{
cout << X[i][j] << " ";
}
cout << endl;
}
}
vector<float> getIrisy()
{
vector<float> y;
ifstream inFile;
inFile.open("y.data");
string sampleClass;
for (int i = 0; i < 100; i++)
{
inFile >> sampleClass;
if (sampleClass == "Iris-setosa")
{
y.push_back(1);
}
else
{
y.push_back(-1);
}
}
return y;
}
vector< vector<float> > getIrisX()
{
ifstream af;
ifstream bf;
ifstream cf;
ifstream df;
af.open("a.data");
bf.open("b.data");
cf.open("c.data");
df.open("d.data");
vector< vector<float> > X;
for (int i = 0; i < 100; i++)
{
char scrap;
int scrapN;
af >> scrapN;
bf >> scrapN;
cf >> scrapN;
df >> scrapN;
af >> scrap;
bf >> scrap;
cf >> scrap;
df >> scrap;
float a, b, c, d;
af >> a;
bf >> b;
cf >> c;
df >> d;
X.push_back(vector < float > {a, b, c, d});
}
af.close();
bf.close();
cf.close();
df.close();
return X;
}
MachineLearning.h:
#pragma once
#include<vector>
using namespace std;
namespace MachineLearning{
class perceptron
{
public:
perceptron(float eta,int epochs);
float netInput(vector<float> X);
int predict(vector<float> X);
void fit(vector< vector<float> > X, vector<float> y);
private:
float m_eta;
int m_epochs;
vector < float > m_w;
vector < float > m_errors;
};
}
MachineLearning.cpp
#include<vector>
#include <algorithm>
#include <iostream>
#include<fstream>
#include <math.h>
#include "MachineLearning.h"
using namespace std;
namespace MachineLearning{
perceptron::perceptron(float eta, int epochs)
{
m_epochs = epochs;
m_eta = eta;
}
void perceptron::fit(vector< vector<float> > X, vector<float> y)
{
for (int i = 0; i < X[0].size() + 1; i++) // X[0].size() + 1 -> I am using +1 to add the bias term
{
m_w.push_back(0);
}
for (int i = 0; i < m_epochs; i++)
{
int errors = 0;
for (int j = 0; j < X.size(); j++)
{
float update = m_eta * (y[j] - predict(X[j]));
m_w[0] = update;
for (int w = 1; w < m_w.size(); w++){ m_w[w] = update * X[j][w - 1]; }
errors += update != 0 ? 1 : 0;
}
m_errors.push_back(errors);
}
}
float perceptron::netInput(vector<float> X)
{
// Sum(Vector of weights * Input vector) + bias
float probabilities = m_w[0];
for (int i = 0; i < X.size(); i++)
{
probabilities += X[i] * m_w[i + 1];
}
return probabilities;
}
int perceptron::predict(vector<float> X)
{
return netInput(X) > 0 ? 1 : -1; //Step Function
}
}
Any kind of help is much appreciated.
Thanks in advance.
Panos P.
After hours of tedious debugging I finally found the mistake. There was a bug in my code when I updated the weights.
for (int j = 0; j < X.size(); j++)
{
float update = m_eta * (y[j] - predict(X[j]));
m_w[0] = update;
for (int w = 1; w < m_w.size(); w++){ m_w[w] = update * X[j][w - 1]; }
errors += update != 0 ? 1 : 0;
}
notice that:
m_w[w] = update * X[j][w - 1]
I am setting the weights as equal to the update. It looks like I forgot a "+" sign. Now it works fine.
Here's it is now:
m_w[w] += update * X[j][w - 1]
Sometimes the silliest mistakes can cause the most annoying of errors.
I hope that this might help anyone making the same mistake.

CodeForces Little Pony and Lord Tirek verdict get different output from my PC

I try to solve this problem.
Little Pony and Lord Tirek
http://codeforces.com/contest/453/problem/E
and here is my solution
/*
HahaTTpro
Little Pony and Lord Tirek
http://codeforces.com/problemset/problem/453/E
*/
#include <iostream>
using namespace std;
struct pony
{
long startMana;
long regenMana;
long maxMana;
long curMana;
};
class Problem
{
private:
pony *Pony;
long totalPonies;
long time;
long totalMana;
void killPony();
void regen(long newtime);
long drain(long target);
public:
~Problem();
void inputPony();
int instruction(long t, long r, long l);
int getTotalPony(){
return totalPonies;
};
};
void Problem::inputPony()
{
cin >> totalPonies;
Pony = new pony[totalPonies];
for (long i = 0; i < totalPonies; i++)
{
cin >> Pony[i].startMana;
cin >> Pony[i].maxMana;
cin >> Pony[i].regenMana;
Pony[i].curMana = Pony[i].startMana;
}
}
void ::Problem::killPony()
{
delete[]Pony;
}
Problem::~Problem()
{
killPony();
}
void Problem::regen(long newtime)
{
long dentatime = newtime - time;
for (long i = 0; i < totalPonies; i++)
{
Pony[i].curMana = Pony[i].curMana + Pony[i].regenMana*dentatime;
if (Pony[i].curMana > Pony[i].maxMana) Pony[i].curMana = Pony[i].maxMana;
}
time = newtime;
}
long Problem::drain(long target)
{
long result = 0;
result = Pony[target].curMana;
Pony[target].curMana = 0;
return result;
}
int Problem::instruction(long t, long l, long r)
{
regen(t);
l--;
r--;
int res=0;
for (long i = l; i <= r; i++)
{
res=res + drain(i);
}
return res;
}
int main()
{
Problem LittlePoNy;
LittlePoNy.inputPony();
long m;
int t, l, r;
cin >> m;
int *Result;
Result = new int[m];
for (long i = 0; i < m; i++)
{
cin >> t >> l >> r;
Result[i] = LittlePoNy.instruction(t, l, r) ;
}
for (int i = 0; i < m; i++)
{
cout << Result[i] << endl;
}
return 0;
}
//wtf ?
and verdict : http://codeforces.com/contest/453/submission/7334245
on my pc
Input
5
0 10 1
0 12 1
0 20 1
0 12 1
0 10 1
2
5 1 5
19 1 5
output
25
58
but on verdict, it got
35
58
How can i fix this ?
It could be that the member variable "time" is not initialized before being used.