I need help understanding where I am going wrong with this solution. Possibly I am doing wrong with modular operations.
This is the problem of recent Codeforces Round #778 , Problem D — Potion Brewing Class
# | User | Rating |
---|---|---|
1 | tourist | 4009 |
2 | jiangly | 3823 |
3 | Benq | 3738 |
4 | Radewoosh | 3633 |
5 | jqdai0815 | 3620 |
6 | orzdevinwang | 3529 |
7 | ecnerwala | 3446 |
8 | Um_nik | 3396 |
9 | ksun48 | 3390 |
10 | gamegame | 3386 |
# | User | Contrib. |
---|---|---|
1 | cry | 167 |
2 | Um_nik | 163 |
3 | maomao90 | 162 |
3 | atcoder_official | 162 |
5 | adamant | 159 |
6 | -is-this-fft- | 158 |
7 | awoo | 157 |
8 | TheScrasse | 154 |
9 | Dominater069 | 153 |
9 | nor | 153 |
I need help understanding where I am going wrong with this solution. Possibly I am doing wrong with modular operations.
This is the problem of recent Codeforces Round #778 , Problem D — Potion Brewing Class
const int N = 2e5+3;
const lli MOD = 998244353;
vector<pair<lli, lli>> a(N);
void dfs(int node, int par, vector<tuple<int,lli,lli>> g[]) {
lli p = a[node].first;
lli q = a[node].second;
for(auto [j,x,y] : g[node]) {
if(j != par) {
a[j].first = (p % MOD * y % MOD) % MOD;
a[j].second = (q % MOD * x % MOD) % MOD;
}
}
for(auto [j,x,y] : g[node]) {
if(j != par) {
dfs(j,node,g);
}
}
}
lli LCM(lli a, lli b) {
return (a*b) / __gcd(a,b);
}
void solve(){
int n;
cin >> n;
vector<tuple<int,lli,lli>> g[n+1];
FOR(k,1,n-1) {
int i,j,x,y;
read(i,j,x,y);
g[i].pb({j,x,y});
g[j].pb({i,y,x});
}
a[1] = {1,1};
dfs(1,0,g);
lli lcm = 1 , ans = 0;
FOR(i,2,n) {
lcm = LCM(lcm, a[i].second);
lcm %= MOD;
}
FOR(i,1,n) {
ans += a[i].first * (lcm/a[i].second);
ans %= MOD;
}
ans /= __gcd(ans,lcm);
cout << ans << '\n';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int t;
cin>>t;
while(t--)
solve();
return 0;
}
Hello Everyone,
I have been stuck at a question for quite some time. I came up with an approach but that's not working for me. Maybe the idea can be correct and implementation can be wrong. So I need some help with an approach. I will add necessary piece of code for showing my approach.
The question is exactly the same and has no typing errors.
Joey and Chandler have plans to go to the Knicks game. However , Joey also wants to try sandwiches from different restaurants before going. He needs to return on time so that Chandler and he can leave for the game. All the N restaurants lie on the same street at positions p[i] and Joey spends time t[i] at the respective restaurants. Joey takes 1 unit of time to travel 1 unit on the path i.e. to travel from position 1 to 3 , he takes 3-1 = 2 units of time. Assuming that Joey starts from 0 , and Chandler and he have to leave for the game in T seconds , can you tell what is the maximum number of restaurants that Joey can cover before leaving.
EXAMPLE Consider N = 3 , T = 10 and pi , ti = [{1,3} , {2,3}]
So the answer is 2.
dp[i][0] -> If he chooses not to stay at the restaurant but travel through here , we only consider time to reach here i.e. p[i]
dp[i][1] -> If he chooses to stay here , we take time spent here into consideration i.e. t[i]
At each position we will take 2 cases : when he decides to stay at the restaurant and when he just passes through this position. At each point we will also check if the total time taken + time to return back is less than or equal to T. If not so we will break from here as we cannot go ahead from here. (I have already sorted according to position).
int dp[n+1][2] , T0 = 0, T1 = 0 , ans = 0;
dp[1][0] = 0 , T0 = inp[1].first;
if(2 * inp[1].first + inp[1].second <= T) {
dp[1][1] = 1 , T1 = inp[1].first + inp[1].second , ans++;
} else {
dp[1][1] = 0 , T1 = inp[1].first;
}
for(int i=2; i<=n; i++) {
dp[i][0] = dp[i][1] = 0;
//dp[i][0]
if(T0 + 2 * inp[i].first - inp[i-1].first <= T) {
dp[i][0] = max(dp[i][0] , dp[i-1][0]);
T0 = T0 + inp[i].first - inp[i-1].first;
}
if(T1 + 2 * inp[i].first - inp[i-1].first <= T) {
dp[i][0] = max(dp[i][0] , dp[i-1][1]);
T0 = T1 + inp[i].first - inp[i-1].first;
}
//dp[i][1]
if(T0 + 2 * inp[i].first - inp[i-1].first + inp[i].second <= T) {
dp[i][1] = max(dp[i][1] , dp[i-1][0] + 1);
T1 = T0 + inp[i].first - inp[i-1].first + inp[i].second;
}
if(T1 + 2 * inp[i].first - inp[i-1].first + inp[i].second <= T) {
dp[i][1] = max(dp[i][1] , dp[i-1][1] + 1) ;
T1 += inp[i].first - inp[i-1].first + inp[i].second;
}
else break;
ans = max({ans , dp[i][1] , dp[i][0]});
}
I just want to know what can be a good approach for this and I will try to implement this on my own.
Hello Everyone,
I am currently learning about sparse table. So after learning basics , I tried to implement it on my own. I thought that it should but I am not able to figure out why it is not working.
So I built table sparse[N][26] , sparse[i][j] gives minimum of the range (i , i + pow(2,j) — 1). Now the problem is :
For a given query range [L , R] , the length of range is R — L + 1. We can represent it as a sum of powers of two so I run a loop for iterating bits and if a bit is set , I made a jump of length pow(2,j) from L. It did not worked for all test cases.
Then I learnt about idempotency and then solved the problem using it. But I want to know why the previous approach is not working.
const int MAXN = 1e5+1;
int sparse[MAXN][26];
void pre(int n , vi &a) {
for(int i=0; i<n; i++) sparse[i][0] = a[i];
for(int j=1; (1<<j) < n ; j++) {
for(int i=0; (i + (1<<j) - 1) < n; i++) {
sparse[i][j] = min (sparse[i][j-1] , sparse[i+(1<<j-1)][j-1]);
}
}
}
int q;
cin >> q;
while(q--) {
int l , r;
cin >> l >> r;
int j = r-l+1;
int ans = INT_MAX;
for(int i=0; i<32; i++) {
if(j & (1<<i))
ans = min(ans , sparse[l][i]);
}
cout << ans << "\n";
}
Thanking you in advance !
Here I want to share my approach towards the problem of May Circuits — Tom and Jerry Love Matrices. Also also I want to ask for help to optimize this.
Worst Case Complexity : O(QLogN)
This gave me TLE in 3 test files but passed all other test files.
Approach : Binary Search
Each cell in matrix has value i+j+X . Since X is common to all we can add this value at the end.
Now there are values in range 2 to N+M and each value has a certain frequency. If you observe carefully , each number num in the range 2 to (N+M)/2 + 1 has frequency equal to min(num-1 , no_of_columns). After that the frequency of remaining numbers can be calculated using the frequency of already calculated numbers. You can observe that in a range of continuous numbers, if we use two pointer like approach , the sum of numbers in the start and end is same.
Eg: [ 2,3,4,5,6,7 ] the sum of 2+7 = 3+6 = 4+5. So we can use this to calculate frequency of numbers in second half.
While making delete range queries , you don't have to actually delete the range but just keep the track of values to be deleted. For eg: if a delete query is delete column 2 to 6 in a row 4 , then value range to be deleted is (4+2) to (4+6).
While searching for a value we can simply perform binary search in the range from 2 to (N+M).
Worst Case When there are all print operations in the queries.
Any help regarding optimizing this is welcome.
Note: It may be a little bit difficult to understand code.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define MAX 1000
#define pb push_back
#define ppb pop_back
#define FOR(i,s,e) for(int i=s; i<=e; i++)
#define RFOR(i,s,e) for(int i=e; i>=s; i--)
#define lli long long int
#define mod 1000000007
#define ppc __builtin_popcount
#define ppcll __builtin_popcountll
#define gs getline(cin, s);
#define c_yes std::cout << "YES" << std::endl;
#define c_no std::cout << "NO" << std::endl;
#define ALL(x) x.begin() , x.end()
typedef pair<int, int> pi;
typedef std::vector<int> vi;
typedef std::vector<vector<int>> vvi;
typedef std::vector<lli> vlli;
typedef std::vector<char> vc;
typedef std::vector<string> vs;
typedef std::vector<pi> vpi;
typedef priority_queue<int> max_heap_int;
typedef priority_queue<string> max_heap_string;
typedef priority_queue<int, vi, greater<int>> min_heap_int;
// class Timer { private: chrono::time_point <chrono::steady_clock> Begin, End; public: Timer () : Begin(), End ()
// { Begin = chrono::steady_clock::now(); } ~Timer () { End = chrono::steady_clock::now();
// cout << "\nDuration: " << ((chrono::duration <double>)(End - Begin)).count() << "s\n"; } } t;
lli row , col , x, q;
vector<pair<lli , lli>> deleted;
lli getCount(lli n) {
lli c = min(col , n-1);
return c*(c+1)/2;
}
//If the number is in the range that has been deleted then decrease the count of this number
lli getDeletedCount(lli val) {
lli cnt = 0;
for(auto &k : deleted) {
if(k.first > val) continue;
else if(val >= k.second) cnt += k.second - k.first + 1;
else if(val >= k.first and val < k.second) cnt += val - k.first + 1;
}
return cnt;
}
lli query(lli k) {
lli low = 2 , high = row+col , sumOfTwoNumbers = row + col + 2 , middle = (low+high) >> 1 ;
bool even = false;
if((row+col) % 2) even = false;
else even = true;
while(low <= high) {
lli mid = (low+high) >> 1;
lli currentCount;
if(mid <= middle)
currentCount = getCount(mid);
else
{
if(!even)
currentCount = 2 * getCount(middle) - getCount(sumOfTwoNumbers - mid - 1);
else
currentCount = 2 * getCount(middle-1) - getCount(sumOfTwoNumbers - mid - 1) + min(middle-1 , col);
}
currentCount -= getDeletedCount(mid);
if(currentCount == k ) return mid;
else if(k < currentCount) high = mid-1;
else low = mid+1;
}
return low;
}
void solve(){
cin >> row >> col >> x >> q;
while(q--) {
int type;
lli a , b , c;
cin >> type;
if(type == 1 || type == 2) { //type 1 | 2 queries
cin >> a >> b >> c;
deleted.pb({a+b , a+c});
}
else { //type 3 queries
cin >> a;
lli qa ;
qa = query(a);
// Answer can not be greater than N+M
if(qa > (row + col)) {
cout << "-1\n";
}
else
cout<< qa + x << "\n";
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
solve();
return 0;
}
Name |
---|