Please subscribe to the official Codeforces channel in Telegram via the link https://t.me/codeforces_official. ×

### guptaji30's blog

By guptaji30, history, 2 months ago, there are 3 types of queries

0 X add a number X, 1 X remove the number X (X always exist), 2 X return the number of subsets that sum to X,

0<=X<=10^3 0<=number of queries <=10^3

I tried to implement this using the knapsack approach but its bound to give TLE

any suggestions? Any help would be appreciated # dp, Comments (50)
 » Auto comment: topic has been updated by guptaji30 (previous revision, new revision, compare).
 » I am a bit confused regarding the time complexity here.X <= 1000, and number of elements is also at-max 1000.In the worst case, assume 1 insertion and then 1 subset query alternating one after another.500 subset queries and for each query you'll need O(N*|X|) operations. So the total operation turns out to be around 500*500*1000 ≈ 2.5e8 operations? Maybe brute forcing using knapsack won't give TLE.
 » I think its very common to add in knapsack in O(size), similarly we can delete from knapsack also in O(size). Code vector dp(1001,0); dp = 1; const int mod = 1e9 + 7; int Q; cin >> Q; while(Q--) { int tt,x; cin >> tt >> x; if(tt == 0) { for(int i=1000;i>=x;--i) dp[i] = (dp[i] + dp[i-x]) % mod; } else if(tt == 1) { for(int i=x;i<=1000;++i) dp[i] = (dp[i] - dp[i-x] + mod) % mod; } else { cout << dp[x] << "\n"; } } Note that the addition part is quite easy, and the subtraction also works the same way(it is clear that the order doesn't matter when we add in the knapsack, intutively you can assume that the last element added was the one to be deleted and try to think how would you undo it).Hope it helps.
•  » » 2 months ago, # ^ | ← Rev. 3 →   This is not correct according to me, we have to calculate number of ways to get sum = X. we cannot undo on knapsack. because number of ways are construct on top of past states, how can we update that. Just curious, with no offense to author as i might also be wrong, do people just upvote anything coming from high rated people or they actually even read the approach and then upvote.
•  » » » No offense, just run a stress test using brute force approach(knapsack with every query) and then do report.
•  » » » » 2 months ago, # ^ | ← Rev. 3 →   if that was possible , we can solve this question easily without two stack approach or divide and conquer which is another method to solve this, so i guess that approach is wrong.link to codeforces edu two pointer problem
•  » » » » » Order matter while adding or deleting in the problem you mention in link that's not the case here !!
•  » » » » » » wait to be clear this are not stack like update, like add X,remove X , X could be anything, so its random deletion.
•  » » » » » » This approach will work here.AC Code
•  » » » » » » » Can we submit this problem anywhere ?
•  » » » » » » » » I send the code for the problem mentioned by Navneet. The approach you mentioned will even work in the problem (my reply was to Aman's comment).
•  » » » » » » » » » Okk cool
•  » » » » » » » » you can try this
•  » » 2 months ago, # ^ | ← Rev. 4 →   I found another flaw in this lets say you are adding 1000 merely 100 times in state, now when the total sum gets around 10^5, and now you have to maintain all those sums, so that when you start removing 1000 again, it does not mess up with your answer. so even if its correct it might not be feasible for the time complexity.we could get around with it some kind of sparse sum states, might not be feasible tho.
•  » » » Just look at the editorial of 1111D - Уничтожить поселение.
•  » » » » 2 months ago, # ^ | ← Rev. 4 →   but we need to maintain more than 10^5 sum right instead of 1000, as i said above, or am i wrong here. because lets say upto some prefix of queries your sum is 1200 and i remove 200, and ask you how many are possible with 1000 sum, so it will still contribute to the answer.so maintaining only upto 1000 is not correct. Also thanks for the problem learnt quite a lot, now i get to know operations are reversible
•  » » » navneet.h if you notice X<=1000 so we need not store or calculate dp states above 1000 as all the queries of type 2 are of form '2 X'. Feel free to correct me.
•  » » » » If you see mathematically or from the code, it seems that it's not needed more than 1000 size but I am not getting intuition why only 1000 states are needed.
•  » » » » » In each of the dp states we are trying to calculate the number of subsets that can be formed with sum being X. And the answer to dp[X] only depends on some dp states for which the sum is less than X. So all dp states for which sum is greater than 1000 are useless as at the end of the day none of them will ever be queried. So why to calculate them? Compute only things which maybe queried in future.
•  » » 2 months ago, # ^ | ← Rev. 2 →   .
 » queries on array???
 » 2 months ago, # | ← Rev. 5 →   We could solve this in $Q * X * sqrt(Q)$ with square root decomposition, i already explained this on our group to someone. Hope at that time it was not live. So basically you can decompose array into square root buckets or now when you remove the element, you can recalculate the current knapsack bucket, as you know the all the element in square root bucket. this will handle for the update part. Complexity of update is $X * sqrt(Q)$ , as there will be only sqrt elements Now for the query part you know the knapsack states, so you can iterate on square root buckets to get number of ways to get sum = X, complexity will be same $X * sqrt(Q)$, for finding the ways part to get sum = X, on first two buckets its just $\sum _{i = 0} ^{ i = X} ways1[i] * ways2[X-i]$, similary you can keep combining those buckets and after this remaining atmost square root element, can be added in this in same way as we did in update. Another way is kind of FFT and segtree, i am not sure about this approach, but we can build convolution tree, someway, i will think this in more detail and write the answer.
•  » » 2 months ago, # ^ | ← Rev. 3 →   imagine people downvoting just because it had some downvotes before and not reading the approach,lol this is also one way to solve this question also feasible btw. The most funny thing is above i made same comment one is getting upvoted and one is downvoted, what kind of people are on codeforces, anyways, no wonder i have stopped caring about downvotes.
•  » » 2 months ago, # ^ | ← Rev. 2 →   I didn't understand your sqrt decom algo, can you please share a code for your algo?Thanks!Wtf wrong with you lowlife smartasses downvoting for asking stuff, you might know everything but I don't, I will ask whenever possible, you cocksukers can go fuck yourself.
 » 2 months ago, # | ← Rev. 3 →   I think knapsack is the way to go. Because the third type of queries only ask for subset sums of $X<=10^3$, we only need the knapsack DP array to be of length 1001. Say we have calculated the DP array for some numbers, then it's easy to calculate a new DP array in $O(maxX)$, extending the set of numbers by adding number X (query type add). Remove queries make it harder. We can use offline deletion from datastructure only supporting insertion and a stack of DP arrays to answer all the queries offline, and support delete. This only costs an extra log factor, and would give a runtime of $O(maxX*Q*log(Q))$Edit: Oh, removing is just as easy as adding, because instead of adding, we know subtract all DP transitions. My approach could still be useful for queries of the form: Is a subset sum of X possible?
•  » » 2 months ago, # ^ | ← Rev. 3 →   you could use number of ways to check if possible or not, like creating a array with subset sum = p * mod,p is whole number. have less probability of failing for random mod and when you randomise more by using more number of mods, chances of failing is even less, for reference you could see code of my friend above for the codeforces edu problem.
 » What is goc33?
 » You didn't write the correct constraints. The actual constraints were 7*1e3 for both 'X' and the queries. That is surely going to make a difference right?
•  » » Not in this case, the solution still would be O(queries * range(x))
•  » » » 2 months ago, # ^ | ← Rev. 2 →   But how? like this guy said. https://codeforces.com/blog/entry/92845?#comment-816270 change 500 to 3500 now and 1000 to 7000. This should surely give TLE now. 3500 * 3500 * 7000
•  » » » » As far as I understand this problem, there are 3 types of queries: insert, delete and number of subsets. Now let's analyse the time taken by each one:1) Insert: you just need a for loop of size O(range(X)) (using the knapsack approach)2) Delete: this query takes same time as Insert, just we would have to use incremental loop than a decremental one.3) Number of subsets: this would run in O(1) time, as you just have to return a direct array entry!So worst case complexity = O(Queries * max(X))
•  » » » » » 2 months ago, # ^ | ← Rev. 2 →   https://codeforces.com/blog/entry/92845?#comment-816278 This was there all this time don't know why I didn't see this. Sorry to bother.
 » Would it be possible for you to share the first question of your test as well?? It would really help!!
•  » » There were a lot of different questions so I will share mine.Q1: given an array with n elements, and Q queries consisting of an integer find whether there exists an element in the array such that it's bitwise and is zero1<=n<10^5 , 1<=q<10^5Q2: Given a binary string, find the number of subsequences with unique values when converted to base10 number.1<=l<10^5
•  » » » How to solve Q2?
•  » » » » From_the_hood Do you get it? I don't understand what are they asking
•  » » » » » If string="101", then count subsequence which in decimal representation are uniqueHere we have0,1,10,101,11so anwer=5
•  » » » » » » 2 months ago, # ^ | ← Rev. 3 →   UPD — I hope this will work Codevector last(2, -1); int n = s.length(); int dp[n + 1]; dp=0; int j=0; while(j
•  » » » » » » » I think this is incorrect, for string="110011", it gives 37, while the answer is 17.
•  » » » » » » » » Fixed Now
•  » » » » » » » 2 months ago, # ^ | ← Rev. 3 →   i think this will also take the subsequences which starts with 0 like 01 but in base10 representation 01 is same as 1.So our final ans must be dp[n]-1-distinct subsequences starting with 0(except '0')
•  » » » » » » » Can you explain the code
•  » » » » » » » » 2 months ago, # ^ | ← Rev. 2 →   https://www.geeksforgeeks.org/count-distinct-subsequences/It's similar to this article, just little optimization for not counting subsequence that start with '0'( For this I've started dp only when 1st '1' appears so that none of the subsequence starting with '0' will be added ).
•  » » » Can you please tell range of ai in Q1?
•  » » » » I have seen this question before the range of ai is also in the same range as n. The question can be solved using SOS DP. By implementing it, the code becomes really short and is easy to understand. If you want, I can share my code here.
•  » » » » » Ohh yes I got it. Range of ai was most important part of the problem :).
•  » » » » » yeah please share the code
•  » » » 2 months ago, # ^ | ← Rev. 2 →   .
•  » » » » I think you will TLE, as at each node you will have more than one path which may potentially contain answer. num & x = 0 them there are many num which satisfy this. Searching for all of them will give you TLE.Feel free to correct me.
 » 2 months ago, # | ← Rev. 2 →   Its addition and deletion on knapsack, I saw this idea here IZho017 bootfall