Ciao a tutti, stavo provando a risolvere i problemi con i range trees, ma in alcuni casi per rangetree2 vado in Execution Timed Out.
Ho utilizzato (ovviamente) un range tree e la lazy propagation per l’update, quindi non capisco quale possa essere il problema. Ho sbagliato l’implementazione della lazy? O ho implementato il range tree in un modo così inefficiente?
#include <iostream>
#include <fstream>using namespace std;
struct nodo
{
int s, e; //inizio e fine del segmento, s == e per i figli
int lazy; //flag per l’update
int mod0; //mod0 = n%3 = 0, mod1 = n%3 = 1, mod2 = n%3 = 2
int mod1;
int mod2;
};void build_tree(int s, int e, int index, nodo tree[])
{
tree[index].s = s;
tree[index].e = e;
tree[index].lazy = 0;
tree[index].mod0 = tree[index].e - tree[index].s + 1;
tree[index].mod1 = tree[index].mod2 = 0;if(s == e) return; build_tree(s, s + (e-s)/2, 2*index, tree); build_tree(s + (e-s)/2+1, e, 2*index+1, tree);
}
void rotate(int &mod0, int &mod1, int &mod2)
{
int c = mod0;
int l = mod1;mod0 = mod2; mod1 = c; mod2 = l;
}
void add_one(int s, int e, int index, nodo tree[])
{
if(tree[index].lazy > 0)
{
for(int i = 0; i < tree[index].lazy; i++)
rotate(tree[index].mod0, tree[index].mod1, tree[index].mod2);if(tree[index].s != tree[index].e) { tree[index*2].lazy += tree[index].lazy; tree[index*2+1].lazy += tree[index].lazy; } tree[index].lazy = 0; } if(tree[index].s > e || tree[index].e < s) return; if(tree[index].s >= s && tree[index].e <= e) { rotate(tree[index].mod0, tree[index].mod1, tree[index].mod2); if(tree[index].e != tree[index].s) { tree[index*2].lazy++; tree[index*2+1].lazy ++; } return; } add_one(s, e, index*2, tree); add_one(s, e, index*2+1, tree); tree[index].mod0 = tree[index*2].mod0 + tree[index*2+1].mod0; tree[index].mod1 = tree[index*2].mod1 + tree[index*2+1].mod1; tree[index].mod2 = tree[index*2].mod2 + tree[index*2+1].mod2;
}
int query(int s, int e, int index, nodo tree[])
{
if(tree[index].s > e || tree[index].e < s) return 0;if(tree[index].lazy > 0) { for(int i = 0; i < tree[index].lazy; i++) rotate(tree[index].mod0, tree[index].mod1, tree[index].mod2); if(tree[index].s != tree[index].e) { tree[index*2].lazy += tree[index].lazy; tree[index*2+1].lazy += tree[index].lazy; } tree[index].lazy = 0; } if(tree[index].s >= s && tree[index].e <= e) return tree[index].mod0; return query(s, e, index*2, tree) + query(s, e, index*2+1, tree);
}
/*void print_tree(int index, nodo tree[])
{
cout << “[” << tree[index].s << ", " << tree[index].e << "] " << tree[index].mod0 << “\n”;if(tree[index].e == tree[index].s) return; print_tree(index*2, tree); print_tree(index*2+1, tree);
}*/
int main()
{
ifstream in(“input.txt”);
ofstream out(“output.txt”);int N, Q; in >> N >> Q; int dim = 2; while(dim < 2*N) dim *= 2; nodo rtree[dim]; build_tree(0, N-1, 1, rtree); //print_tree(1, rtree); int com, s, e; for(int i = 0; i < Q; i++) { in >> com >> s >> e; if(com == 0) add_one(s, e, 1, rtree); else out << query(s, e, 1, rtree) << endl; } // cout << "End of input\n"; // print_tree(1, rtree); return 0;
}